您的位置:

解决TLS握手失败的方法和原因

Transport Layer Security (TLS) 协议加密了网络连接以保护敏感数据。然而,它也可能成为故障排查中必须考虑的一个因素。在本篇文章中,我们将探讨TLS握手失败的原因和方法,并给出相关代码示例。

一、缺少证书

在TLS握手中,服务器和客户端都需要证书。如果其中一方未提供证书,会发生握手失败。证书错误可能有多种不同的原因。

服务器证书过期或未签署颁发者的根证书,客户端会认为无法验证和信任该证书,从而拒绝对其进行连接。一种可能的解决方案是获取新的证书或更新证书。

当客户端接收到证书链时,它会尝试在受信任的证书颁发机构(CA)列表中查找匹配的CA,如果找不到,就会返回“未知的CA”的错误。为避免这种情况,开发人员需要确保使用公认的CA,这样客户端就能成功验证服务器的证书。另外,开发人员也可以在程序代码中将这些CA添加到信任列表中。


const SSL_CA_CERT_FILE = "ca-cert.pem";

$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'cafile', SSL_CA_CERT_FILE);

二、Ciphersuite问题

TLS协议会协商双方连接使用的加密套件,因此服务器和客户端必须支持共同的加密算法、密钥协商算法和摘要算法,否则TLS握手就无法成功。

如果服务器未启用客户端请求的加密套件,则客户端将无法与服务器进行TLS握手。在这种情况下,可以在服务器上启用所需的加密套件或控制代码以使用受服务器支持的套件。

如果服务器/客户端启用了过时的加密套件,可能存在安全风险。因此,开发人员必须遵循最佳实践,使用经过国际认可的加密套件。


const SSL_CIPHERS = "AES128-SHA256";

$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'ciphers', SSL_CIPHERS);

三、证书链问题

服务器证书链可能与CA的颁发机构不匹配,这可能会导致TLS握手失败。在这种情况下,客户端会收到“证书链不完整”的错误消息。

通常,服务器证书应包括与由客户端信任的根证书相匹配的中间CA证书。如果中间证书已过期,则需要更新证书。如果客户端自己使用私有CA,开发人员可以选择在代码中提供相应的证书链。


const SSL_CERTFILE = "server.pem";
const SSL_CHAINFILE = "ca.pem";

$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'local_cert', SSL_CERTFILE);
stream_context_set_option($context, 'ssl', 'local_pk', SSL_KEYFILE);
stream_context_set_option($context, 'ssl', 'verify_peer', true);
stream_context_set_option($context, 'ssl', 'verify_peer_name', true);
stream_context_set_option($context, 'ssl', 'verify_depth', 5);
stream_context_set_option($context, 'ssl', 'cafile', SSL_CHAINFILE);

四、TLS版本

最后一个常见的TLS握手失败的原因是支持的TLS版本不匹配。TLS 1.1和TLS 1.2已由许多浏览器和服务器使用。如果服务器不支持2个版本的TLS,客户端将无法与该服务器建立安全连接。

开发人员必须确定服务器是否支持与客户端请求的TLS版本。如果客户端支持TLS 1.2和TLS 1.3而服务器不支持,则为了保证安全性,应考虑升级服务器TLS版本。


const SSL_TLSVERSION = STREAM_CRYPTO_METHOD_TLSv1_2_SERVER

$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'crypto_method', SSL_TLSVERSION);

总结

在本文中,我们探讨了TLS握手失败的原因和解决方案。缺少证书、Ciphersuite问题、证书链问题和TLS版本可能会导致TLS连接失败。开发人员应努力确保服务器和客户端都安装且支持TLS配置正确,以便更好的应用程序安全性和性能。