我遇到了一个SSL/TLS握手错误,消息是“坏证书”,同时试图在PHP中使用stream_socket_client建立安全连接。目标是将我们的PHP应用程序与需要SSL/TLS加密的外部服务集成。
下面是相关的代码片段:
private function createSocketConnection($host, $port)
{
// Path to the client certificate and private key
// $localCertificateFile = '/var/www/sslcert/suezpublic.crt';
// $privateKeyFile = '/var/www/sslcert/privatekesy.pem';
// Create a secure SSL/TLS context with client certificates
$contextOptions = [
'ssl' => [
'local_cert' => '/var/www/sslcert/suezcombined.pem',
// 'local_pk' => '/var/www/sslcert/privatekesy.pem',
'cafile' => '/var/www/sslcert/bizswitch.pem', // GoDaddy Intermediate certificate or your CA certificate
'verify_peer' => true, // Enable peer certificate verification
'verify_peer_name' => true, // Check that the common name exists and matches the host name
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, // Use TLSv1.2
// 'crypto_timeout' => 30, // Increase the handshake timeout to 30 seconds
'CN_match' => 'www.suezelectric.com', // Ensure the common name matches the server's hostname
'ciphers' => 'HIGH:!SSLv2:!SSLv3', // Specify allowed ciphers for security
'disable_compression' => true, // Disable SSL/TLS compression for security
'capture_peer_cert' => true,
'capture_peer_chain' => true,
// 'allow_self_signed' => true,
'debug' => true, // Enable SSL debugging
],
];
$context = stream_context_create($contextOptions);
// Create a TCP/IP socket connection
$socket = stream_socket_client("tls://$host:$port", $errno, $errstr, 30);
if ($socket === false) {
throw new Exception("Failed to create socket: [$errno] $errstr");
}
// Enable SSL/TLS on the stream
$secured = stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);
if ($secured === false) {
throw new Exception("Failed to enable SSL/TLS on the socket");
}
return $socket;
// Now you can use the $socket to send/receive data with the server using SSL/TLS
// For example, you can use fwrite($socket, $data) to send data to the server.
}
字符串
本人已验证以下内容:
- 客户端证书(public_cert.crt)和私钥(private_key.pem)有效且正确匹配。
- 提供CA证书(server_cert.pem),其中包含必要的中间证书。
- STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT和“ciphers”设置与服务器的配置兼容。
有趣的是,当服务器管理员在服务器端禁用身份验证时,SSL/TLS握手成功完成。但是,当启用身份验证时,会发生“坏证书”错误,并且还注意到服务器正在接收空证书链。
我已经尝试使用error_log进行调试,并验证证书文件的路径是否正确。
在PHP中使用stream_socket_client时,我的SSL/TLS配置中是否缺少了什么,或者是否有任何潜在的陷阱可能导致此错误?
对此问题的任何指导或见解将不胜感激。谢谢你,谢谢
1条答案
按热度按时间kse8i1jr1#
感谢@miken32为我指出资源https://www.php.net/manual/en/context.ssl.php,我已经能够解决我的问题。因此,我想我应该把它作为一个答案
字符串
这样,我就成功地建立了到服务器的SSL连接。同样值得注意的是,当使用
stream_socket_client()
连接到socket时,旧方法如socket_write
、socket_read
和socket_close
将不再起作用。我将它们分别更改为fwrite
、fread
和fclose