允许公众从您的私钥生成 CSR

信息安全 x.509
2021-08-13 02:45:49

作为托管服务提供商,我想让为客户的域生成证书的过程尽可能方便。

我正在考虑创建一个网页,任何人都可以:

  • 从我们的私钥生成给定主机名的 CSR
  • 拿走 CSR 并带着证书返回给我们

允许任何人根据我们的私钥生成潜在的数千个 CSR 是否有任何危险?


解决一些疑虑/问题:

我认为这里真正的危险是在很多域中重复使用相同的私钥。

它与拥有多个 SAN 的单个证书真的有什么不同(从安全的角度,而不是管理的角度)吗?例如,我们的 Cloudflare CDN 提供的证书具有以下 SAN:

DNS:ssl2917.cloudflare.com, DNS:*.app.com.pk, DNS:*.boldstatementmarketing.com, DNS:*.lacasadivetro.com, DNS:forospyware.com, DNS:*.reportcrowd.com, DNS:*.vladtv.com, DNS:*.1bse.com, DNS:*.discourse.org, DNS:*.forospyware.com, DNS:*.gossipbrigade.com, DNS:*.gsmcodigos.com, DNS:*.is.gl, DNS:*.madepal.co, DNS:*.mejorando.la, DNS:*.oceanvillageresort.com, DNS:*.pinside.com, DNS:*.ratelossprogram.com, DNS:*.soopermexican.com, DNS:*.tequierocali.org, DNS:1bse.com, DNS:app.com.pk, DNS:boldstatementmarketing.com, DNS:discourse.org, DNS:gossipbrigade.com, DNS:gsmcodigos.com, DNS:is.gl, DNS:lacasadivetro.com, DNS:madepal.co, DNS:mejorando.la, DNS:oceanvillageresort.com, DNS:pinside.com, DNS:ratelossprogram.com, DNS:reportcrowd.com, DNS:soopermexican.com, DNS:tequierocali.org, DNS:vladtv.com

是否存在现实情况,您有理由相信一个站点的密钥已泄露,而其他站点的密钥仍然安全。

并不真地。如果使用这些密钥之一的客户请求移动他的站点,我们将不会分发密钥。

您应该为您生成的每个 CSR 生成一个新的私钥。

对,我们应该。这是一个为了安全而牺牲便利(在我们这边)的例子。对于银行业,地狱没有。论坛网站?可能值得。

您在设置中真正需要考虑的是 CSR 的完整性。客户需要绝对确定,他们签署的 CSR 中的公钥确实是正确的公钥。

想一想,这里最好的选择可能是放弃生成 CSR 的要求……我们可以只向每个人分发一个 CSR 并让他们用他们喜欢的主机名签名(类似于startssl所做的 - 签名时他们丢弃请求的主机名并使用您在其网页上输入的内容的 CSR。

我不知道是否所有(任何?)CA 都会这样做,但这是一种选择。

3个回答

从理论上讲,只要系统足够安全,并且您只在单独的服务器上签署 CSR,保持该密钥安全,就不会有问题。

然而,

  • 如果您确实以某种方式泄露了该私钥,会发生什么?
  • 如果发生违规行为,您的计划是什么?
  • 您是否会在与签名服务器相同的服务器上拥有TLS 证书的私钥

问问自己:对 1000 多个域使用相同的密钥有什么好处?您能向您的客户解释单点故障吗?

此外,RSA(至少)目前没有已知的用于重复签名的攻击会泄露密钥。那个是为 DSA 保留的,带有一个狡猾的 PRNG。

不过,这是个坏主意。

更新

在这种情况下,您想要的系统如下:

  1. 每个客户都被监禁(通过chroot())进入服务器上他们自己的目录
  2. 对于生成的每个 CSR,都会在用户的监狱中生成一个私钥,但在 webroot 之外。
    • 例如 /jail/customername/private/server.key
    • /jail/customername/domains/<domain>/subdomains/<subdomain>/public
    • /jail/customername/domains/<domain>/public
    • /jail/a/domains/a.com/public/, 等等。
  3. 网络服务器必须尊重监狱,并且脚本语言必须以无法访问每个用户监狱中的私人文件夹的用户身份运行。

这个系统不会有问题;我假设您正在运行一个共享主机系统,并且您想要一种简单的方法来为每个客户生成 CSR 以启用 TLS。

这样,您就可以为每个客户正确且强制地分离权限,并且如果客户受到威胁(除非有任何本地权限提升漏洞),您的基础设施的其余部分是健全的,您只需撤销用户的 TLS 证书被利用了。

除了重复使用私钥本身之外,为同一个私钥创建大量 CSR 没有任何危险。

CSR 包含:

  • 证书申请信息(主题等)
  • 公钥
  • 上面的签名,使用私钥

据我所知,从来没有出现过使用私钥重复签名会降低私钥安全性的情况。如果有,我们都会有麻烦。

然而为许多域重新使用相同的私钥是一个糟糕的主意。您应该为您生成的每个 CSR 生成一个新的私钥。一旦你开始这样做,可能会有一些麻烦!攻击者可能会生成大量私钥,这反过来会减少系统上的可用熵,(假设)导致私钥更可预测。

我最初写了一个评论,其中包含两个可能的问题,然后意识到可能还有一个更大的问题需要回答。

假设 Web 服务器、操作系统或其他允许 PHP 应用程序访问私钥的地方存在(到目前为止,假设的)零日漏洞。通常,这只能通过插入恶意 PHP 文件来利用。这将是一个严重的漏洞,但只能通过允许未经授权上传 PHP 脚本的其他漏洞远程利用。

如果您共享私钥,这样的漏洞将成为灾难性的。攻击者所要做的就是向您注册一个帐户,上传 PHP 漏洞利用,然后他就会立即拥有数千个其他网站的私钥。

同样,在您的场景中,像 Heartbleed 之类的东西不仅会破坏一个站点,而且会立即为您的所有客户泄露私钥,从而使这个已经很严重的问题变得完全是灾难性的。