在 SSL 握手期间,是否在 SSL 握手期间检查了服务器的域名,我的意思是服务器中的域名是否与服务器正在运行的域进行了核对?
示例:假设服务器证书具有域 mydomain.com 。如果服务器在域 someotherdomain.com 中运行......这是否在 SSL 握手期间被检查并中止,因为 mydomain.com 不是 someotherdomain.com ?
这取决于...
SSL/TLS 标准本身并未指定验证服务器证书的方式和时间。
从介绍:
[...] 关于如何启动 TLS 握手以及如何解释交换的身份验证证书的决定留给在 TLS 之上运行的协议的设计者和实施者来判断。
话虽如此,虽然它没有指定如何进行身份验证,但实现是为了在握手期间(或至少在握手之后)执行此检查:
bad_certificate
, certificate_expired
, ...)。在大多数情况下,证书验证本身由RFC 3280 / RFC 5280指导。默认情况下,许多 SSL/TLS 堆栈至少会执行此操作。
主机名验证可被视为证书身份验证步骤之一,历来是单独实施的。这主要是因为 RFC 3280/RFC 5280 没有解决这一步,把它留给了每个应用协议。在RFC 6125中有一个相对较新的协调尝试(您可以在附录 B 中找到协议的差异)。
在 SSL/TLS 握手期间是否进行主机名检查取决于您使用的库以及您如何配置它。
SSLSocket
例如,在 Java 7 之前,这必须与主 JSSE API ( / )分开完成SSLEngine
。(HttpsURLConnection
例如,这是在 JSSE 中完成的,但它位于 JSSE 之上,而不是在其中。)从 Java 7 开始,可以在握手期间和在 JSSE 中使用 来执行此检查X509ExtendedTrustManager
,但这必须使用SSLParameters.setEndpointIdentificationAlgorithm(...)
,仅支持HTTPS
andLDAPS
(也就是说,即使您的服务不使用 HTTP,使用HTTPS
端点识别算法也不会是一个糟糕的选择,当然总比没有好)。
其他 SSL/TLS 库或用其他语言包装其他库往往至少对此有回调。开发人员是否使用(和正确使用)它们取决于,如本文所示。(您可能也对 Security.SE 上的这个问题感兴趣。)
不,主机名检查是 HTTPS 的一部分,而不是 SSL。
是的。在 SSL 握手期间,正确的客户端应将其连接的主机名与证书中指定的域名进行比较。不这样做会使 TLS 无用,否则 MITM 攻击将是微不足道的。
请注意,存在许多写得不好的软件,它们接受任何提供的证书,但没有进行正确的证书验证。最近有关于Android软件的这个问题的报告。似乎提供的数以千计的软件标题(主要是免费软件)没有执行适当的验证,从而给用户带来了安全风险。