我想在通过 TLS 1.2 保护的两个应用程序之间建立通信,其中端点的公钥是固定的。(不涉及证书颁发机构。)
此外,我什至不想处理证书;只是 RSA/ECDSA 公钥。
具体来说,它们都是 PHP 应用程序,我使用 curl 来促进通信。
以前有人做过吗?
最后这个特性已经在 PHP 中实现了,你也可以在旧的 PHP 版本中使用它,只要你的 cURL 版本足够!
您可以使用 DER 格式的公钥的 SHA-256 哈希值进行固定。不要将此与证书指纹混淆! 您将在此处固定公钥,而不是证书。
最好参考官方 cURL 文档来提取此密钥。但是可能有一种更简单的方法:引脚的格式与HPKP中使用的格式相同。因此,如果网络服务器使用 HPKP ,我强烈建议您使用它发送的哈希值!您可以简单地从标题中复制并粘贴它们。您只需要稍微更改格式,如下所示。
Public-Key-Pins: pin-sha256="cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs="; pin-sha256="M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE="; max-age=5184000;
到达:
sha256//cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=;sha256//M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE
但是请注意,HPKP 和 CURL 之间有一个很大的区别CURLOPT_PINNEDPUBLICKEY
:在 HPKP 中,您可以固定中间证书的公钥,而在使用 CURL 时,您目前不能这样做!
由于已经有很多 HPKP 教程,您还可以找到其他好的指南来创建这些哈希值。例如,使用Scott Helme的现有证书文件的单线:
openssl x509 -pubkey < tls.crt | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
选项的格式最终如下所示。您可以根据需要固定任意数量的密钥,我还建议您至少固定一个当前未使用的备份密钥,这样您就可以在服务器损坏或类似情况下轻松切换密钥。
sha256//Base64EncodedHashOfPublicKey;sha256//Base64EncodedHashOfAnotherPublicKey
或者,如果需要,您也可以指定证书文件的路径。
在 PHP 中你可以像这样使用它:
<?php
// this line makes it possible to use that option in PHP < 7.0.7
defined('CURLOPT_PINNEDPUBLICKEY') || define('CURLOPT_PINNEDPUBLICKEY', 10230);
$ch = curl_init("https://example.com");
curl_setopt($ch, CURLOPT_PINNEDPUBLICKEY, "YourPinsHere!!");
// ...
之后你应该通过指定一个无效的引脚来测试它。如果它没有失败,要么你的要求没有得到满足,要么你在实现它时出错了。您还可以使用以下命令在控制台上对其进行测试:
curl https://example.com --pinnedpubkey "YourPinsHere!!"
我不知道解决方案,但我可以为您提供一些发现方向:
看看http://php.net/manual/en/function.curl-setopt.php 特别是 CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 选项。不允许验证完整的公钥,只能验证其 md5 哈希。
作为另一种变体,您可以通过控制台实现自己的处理 CURL 的服务。它允许您将任何选项传递给 curl。它超出了默认的 curl 库。
(不涉及证书颁发机构。)
默认情况下,curl 设置为不信任任何 CA。所以就是这样。无需详细说明或基于意见的回复,这里有一个组织良好的“固定备忘单”,可能对您有所帮助:https ://www.owasp.org/index.php/Pinning_Cheat_Sheet (无需赏金<3 )