我想在通过TLS 1.2保护的两个应用程序之间建立通信,其中端点的公钥被固定。 (没有涉及证书颁发机构。)
此外,我甚至不想处理证书;只是RSA / ECDSA公钥。
具体来说,它们都是PHP应用程序,我使用curl来促进沟通。
有没有人之前完成过这个?
答案 0 :(得分:4)
最后这个功能已经在PHP中实现,只要您的cURL版本足够,您也可以在旧的PHP版本中使用它!
您可以使用DER格式的公钥的SHA-256哈希值进行固定。 请勿将此与证书指纹混淆! 你在这里固定公钥,而不是证书。
最好引用official cURL documentation来提取此密钥。 但是可能有一种更简单的方法:引脚的格式与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时openssl x509 -pubkey < tls.crt | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
{3}}不能这样做!
由于已经有很多HPKP教程,您还可以找到创建这些哈希的其他好指南。这是例如使用现有证书文件currently的单行代码:
<?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!!");
// ...
选项的格式最终如下所示。您可以根据需要固定多个密钥,我还建议至少固定一个当前未使用的备份密钥,以便在发生服务器泄露或类似情况时轻松切换密钥。
SHA256 // Base64EncodedHashOfPublicKey; SHA256 // Base64EncodedHashOfAnotherPublicKey
或者,您也可以根据需要指定证书文件的路径。
在PHP中,您可以像这样使用它:
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
之后你应该通过指定无效的引脚来测试它。如果它没有失败,则要么不满足您的要求,要么在实现它时出错。 您也可以使用以下命令在控制台上测试它:
curl by Scott Helme --pinnedpubkey&#34; YourPinsHere !!&#34;
答案 1 :(得分:3)
我不知道解决方案,但我可以为您提供一些发现方向:
看看http://php.net/manual/en/function.curl-setopt.php 特别是在CURLOPT_SSH_HOST_PUBLIC_KEY_MD5选项中。它不允许验证完整的公钥,只是它的md5哈希值。
作为另一种变体,您可以通过控制台实现处理CURL的自己的服务。它允许您传递任何卷曲选项。它没有默认的卷曲库。
答案 2 :(得分:2)
(不涉及证书颁发机构。)
默认情况下,curl设置为不信任任何CA.所以就是这样。 并且没有详细介绍或基于意见的回复,这里有一个组织良好的&#34; Pinning Cheat Sheet&#34;这可能对你有所帮助:https://www.owasp.org/index.php/Pinning_Cheat_Sheet(没有必要的赏金&lt; 3)