Bob Ortiz Asked: 2016-07-08 02:07:01 +0800 CST2016-07-08 02:07:01 +0800 CST 2016-07-08 02:07:01 +0800 CST 我可以在 LetsEncrypt 中使用 Public-Key-Pins 吗? 772 当我设置 cronjob 以每 30 天更新 LetsEncrypt 证书时,我可以设置 Public-Key-Pins 吗? 如果证书被更新,那么公钥密码也会被更新,对吗? ssl ssl-certificate http-headers public-key tls 3 个回答 Voted Best Answer gxx 2016-07-08T03:00:41+08:002016-07-08T03:00:41+08:00 一些谨慎的话开始: 如果您计划实施 HPKP,请了解您在做什么。 如果您做的不正确,或者“如果发生了坏事”,这些都不受您的控制,您可能会导致您的域无法使用。 请务必使用不那么重要的域或非常短的缓存时间(例如十秒)来测试您的设置。 考虑一下您要固定哪些证书:根证书、中间证书、叶子证书... 考虑一下固定另一个(备份)证书颁发机构是否有意义,它是中间证书和您的叶证书。 安全总比后悔好:想想是否有必要固定另一个备份 CA / cert,拥有两个。 如果这些观点和问题对您来说听起来“新”:在实施之前,请阅读 HPKP 的内容以及常见的陷阱和警告。 我可以在 LetsEncrypt 中使用 Public-Key-Pins 吗? 是的。 如果证书被更新,那么公钥密码也会被更新,对吗? 这取决于您所指的证书以及您要固定的证书。 Barry Pollard 2016-07-10T02:27:49+08:002016-07-10T02:27:49+08:00 会回应 gf_ 所说的一切。 但是,要回答这个问题,是的,您可以。 默认情况下,Let's Encrypt 在续订时重新创建密钥和证书。如果您想在叶子上固定,这使得实现 HPKP 变得困难,您可能应该这样做以防中间更改(就像 2016 年 3 月所做的那样)。 因此,如果您仍想执行 HPKP,您有多种选择: 使用您自己的固定 CSR,而不是每次为您创建 CSR 的标准客户端,这样叶键就不会改变。这篇博文专门解释了如何做到这一点,因为作者使用的是 HPKP。 使用较短的 HPKP 到期时间并在该到期时间内更新并更改策略以在实际更改证书之前同时拥有旧密钥和新密钥,并有足够的时间让任何访问者获取新策略。 固定 Let's Encrypt 根而不是叶子或证书。 bviktor 2017-01-17T12:00:46+08:002017-01-17T12:00:46+08:00 我刚刚使用带有 dns01 验证的脱水客户端实现了这一点。dns01 挂钩是certzure,因为我们的 DNS 托管在 Azure 中。 编辑:当我谈论私钥时,显然我的意思是你只将公钥部分变成引脚。顾名思义,私钥应始终保持私密。有关实现细节,请参见我自己的钩子。 您需要私钥翻转才能实现这一点。也就是说,您始终拥有当前的私钥(称为 A)和未来的私钥(称为 B),这样您就可以将它们都添加到您的 pin 中。因此,此时您的密码是 A 和 B。当证书更新的那一天到来时,私钥 A 变得过时,而 B 变得有效。同时你得到一个新的未来私钥,称之为 C。你重新生成你的 pin 列表,现在它包含 B 和 C。这就是你如何滚动你的私钥。脱水现在支持这一点。 此外,您需要在每次更新证书时调用一个钩子,从而翻转您的私钥。我自己实现了这个。 最后,如果我做对了,你必须确保: HPKP age x 2 < days between cert renewals 例如,如果您的 HPKP 年龄为 50 天,并且您每 30 天更新一次证书,则在第一天访问您网站的客户将被私钥 A 和 B 卡住,而您在第 31 天滚动到 B 和 C。服务器有 B 和 C,客户端有 A 和 B,即使在第 50 天也有匹配,并且客户端正确打开了站点。 但是让我们看看 HPKP 年龄是否为 70 天。您每 30 天更新一次证书,并且客户在第一天访问了您的站点,因此,它再次只有私钥 A 和 B。您在第 31 天滚动到 B 和 C,并在第 61 天滚动到 C 和 D . 您的服务器有 C 和 D,客户端有 A 和 B,没有匹配项,从第 61 天到第 71 天,客户端的 HPKP 策略到期时,都会给客户端竖中指。 另一个可能更安全,当然也更简单的选择是每次都使用相同的私钥并生成一个或多个备份私钥,然后将它们硬编码到您的 HPKP 配置中并使用它来完成。 是的,这很棘手,可能有一些我没有想到的警告,但从长远来看,我们会看到的。显然,我将它部署在一个 HPKP 寿命短(15 天)的非关键子域上,这样它就不会造成巨大的麻烦。 编辑:我编写了一些脚本来帮助您使用 Let's Encrypt 设置 HPKP 并使用 Nginx 进行脱水: HPKPinx
一些谨慎的话开始:
会回应 gf_ 所说的一切。
但是,要回答这个问题,是的,您可以。
默认情况下,Let's Encrypt 在续订时重新创建密钥和证书。如果您想在叶子上固定,这使得实现 HPKP 变得困难,您可能应该这样做以防中间更改(就像 2016 年 3 月所做的那样)。
因此,如果您仍想执行 HPKP,您有多种选择:
我刚刚使用带有 dns01 验证的脱水客户端实现了这一点。dns01 挂钩是certzure,因为我们的 DNS 托管在 Azure 中。
编辑:当我谈论私钥时,显然我的意思是你只将公钥部分变成引脚。顾名思义,私钥应始终保持私密。有关实现细节,请参见我自己的钩子。
您需要私钥翻转才能实现这一点。也就是说,您始终拥有当前的私钥(称为 A)和未来的私钥(称为 B),这样您就可以将它们都添加到您的 pin 中。因此,此时您的密码是 A 和 B。当证书更新的那一天到来时,私钥 A 变得过时,而 B 变得有效。同时你得到一个新的未来私钥,称之为 C。你重新生成你的 pin 列表,现在它包含 B 和 C。这就是你如何滚动你的私钥。脱水现在支持这一点。
此外,您需要在每次更新证书时调用一个钩子,从而翻转您的私钥。我自己实现了这个。
最后,如果我做对了,你必须确保:
例如,如果您的 HPKP 年龄为 50 天,并且您每 30 天更新一次证书,则在第一天访问您网站的客户将被私钥 A 和 B 卡住,而您在第 31 天滚动到 B 和 C。服务器有 B 和 C,客户端有 A 和 B,即使在第 50 天也有匹配,并且客户端正确打开了站点。
但是让我们看看 HPKP 年龄是否为 70 天。您每 30 天更新一次证书,并且客户在第一天访问了您的站点,因此,它再次只有私钥 A 和 B。您在第 31 天滚动到 B 和 C,并在第 61 天滚动到 C 和 D . 您的服务器有 C 和 D,客户端有 A 和 B,没有匹配项,从第 61 天到第 71 天,客户端的 HPKP 策略到期时,都会给客户端竖中指。
另一个可能更安全,当然也更简单的选择是每次都使用相同的私钥并生成一个或多个备份私钥,然后将它们硬编码到您的 HPKP 配置中并使用它来完成。
是的,这很棘手,可能有一些我没有想到的警告,但从长远来看,我们会看到的。显然,我将它部署在一个 HPKP 寿命短(15 天)的非关键子域上,这样它就不会造成巨大的麻烦。
编辑:我编写了一些脚本来帮助您使用 Let's Encrypt 设置 HPKP 并使用 Nginx 进行脱水:
HPKPinx