[英]How to set trusted certificate authorities list to socket client in PHP?
在IHE Connectathon的上下文中,我想創建一個響應ATNA配置文件的原始套接字服務器,它需要具有兩端證書的TLS套接字。
如果在此消息中總結我的問題: https : //groups.google.com/d/msg/eu_connectathon/O-VGI_3cltw/ARsElA65ZkkJ
編輯 :對不起,Google網上論壇不公開,以下是留言:
嗨弗洛里安,
錯誤消息“服務器要求提供證書,但發布者列表不包含有效的證書頒發機構”究竟是什么? 是指並且在過去幾年中TLS工具客戶端的實施發生了變化,還是我使用了錯誤的證書?
該消息表示服務器已將CertificateRequest消息發送到clienmt,而certificate_authorities字段中沒有值。
我去年遇到了這個問題,並與TLS工具的開發人員討論過這個問題。 他聲稱,如果服務器不包含此字段,客戶端將無法確定要返回哪種類型的證書,假設您將連接頂部多個關聯域,每個域都有自己的CA.
您似乎可以通過調用SSL_CTX_set_client_CA_list來指示OpenSSL返回此值,例如在DcmTLSTransportLayer :: addTrustedCertificateFile中。 我還沒有使用TLS工具測試過這個,但我希望在connectathon啟動之前完成它。
但是我在PHP中的實現與它們的實現並不相同。 看起來PHP缺少“SSL CTX設置客戶端CA列表”的可能性,告訴客戶端它應該使用哪個證書頒發機構。
$context = stream_context_create();
if ($certificate) {
// Server certificate + private key
stream_context_set_option($context, 'ssl', 'local_cert', "/path/to/server.pem");
stream_context_set_option($context, 'ssl', 'passphrase', $passphrase);
// Client public certificates
stream_context_set_option($context, 'ssl', 'cafile', "/path/to/ca.pem");
stream_context_set_option($context, 'ssl', 'allow_self_signed', false);
stream_context_set_option($context, 'ssl', 'verify_peer', true);
stream_context_set_option($context, 'ssl', 'peer_name', "TlsTools2");
stream_context_set_option($context, 'ssl', 'capture_peer_cert', true);
stream_context_set_option($context, 'ssl', 'capture_peer_cert_chain', true);
}
$this->__socket = @stream_socket_server("tcp://$address:$port", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context);
IHE Gazelle TLS客戶端告訴我“服務器要求提供證書,但發布者列表不包含有效的證書頒發機構。”
客戶端和服務器之間的消息傳遞,但測試不正常,因為“不夠安全”,告訴消息。
你看到了一個問題嗎?PHP有沒有我沒看到的更多選項?
謝謝你的幫助。
編輯 :正如@rdlowrey建議我,我剛剛創建了一個錯誤報告: https ://bugs.php.net/bug.php?id = 69215
正如我在最初的評論中所提到的:
PHP的流服務器實現從未實際使用SSL_CTX_set_client_CA_list()來加密流。
這已在相關錯誤報告中引用的上游更正:
https://bugs.php.net/bug.php?id=69215
一旦發布了PHP 5.6.8二進制文件(或者您可以在該版本之前針對當前源手動構建PHP),將反映此更改。
使用更新的二進制文件,OP的示例代碼將按預期工作而無需修改。 在服務器中使用的加密上下文的簡單示例:
<?php
$serverCtx = stream_context_create(['ssl' => [
'local_cert' => '/path/to/my-server-cert.pem',
'passphrase' => 'elephpant',
'cafile' => '/path/to/my-ca-certs.pem',
'verify_peer' => true
]]);
在上面的示例中,當作為TLS握手的一部分發送客戶端CA列表時,PHP會自動使用my-ca-certs.pem
的my-ca-certs.pem
文件中的證書名稱。
通過"verify_peer" => true
啟用加密服務器流中的對等驗證時,PHP將不會自動啟用對等名稱驗證。 除非您只希望允許單個證書持有者(具有特定的已知名稱)訪問您的服務器,否則這正是您想要的。 此默認行為支持更常見的用例,即允許其證書由可信CA簽名的任何客戶端建立與服務器的連接。 但是,如果您希望在加密服務器中強制執行名稱驗證,請修改上面的上下文示例,如下所示:
<?php
$serverCtx = stream_context_create(['ssl' => [
'local_cert' => '/path/to/my-server-cert.pem',
'passphrase' => 'elephpant',
'cafile' => '/path/to/my-ca-certs.pem',
'verify_peer' => true,
'verify_peer_name' => true, // verify the name on the cert
'peer_name' => 'zanzibar' // ensure the cert's name matches this
]]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.