在SSL握手期间,服务器证书中的域名是否会被检查?我的意思是,在运行服务器的域中,服务器证书中的域名是否与之匹配?
例如:假设服务器证书的域名为mydomain.com。如果服务器在someotherdomain.com域中运行...这在SSL握手期间是否会被检查并中止连接,因为mydomain.com不是someotherdomain.com?
这要看情况而定...
SSL/TLS标准本身并未规定服务器证书的验证方式和时间。
从introduction中可以得知:
[...] TLS握手的启动方式以及认证证书的解释方式,由运行在TLS之上的协议的设计者和实现者自行决定。
尽管它没有规定认证的具体方式,但是实现应该在握手过程中(或者至少在握手后立即)执行此检查:
bad_certificate
,certificate_expired
,...)。在大多数情况下,证书验证本身是由RFC 3280/RFC 5280指导的。许多SSL/TLS堆栈至少会默认执行此操作。
主机名验证可以被视为证书认证步骤之一,历史上一直是单独实现的。这主要是因为RFC 3280/RFC 5280没有涉及此步骤,而是留给每个应用协议。在RFC 6125中有一个相对较新的协调尝试(您可以在附录B中找到协议的差异)。SSLSocket
/SSLEngine
) 分开完成。(例如在HttpsURLConnection
中完成,但这是在JSSE之上而不是在其中完成。) 自Java 7以来,可以在握手期间和使用X509ExtendedTrustManager
在JSSE内执行此检查,但这必须使用SSLParameters.setEndpointIdentificationAlgorithm(...)
进行配置,它仅支持 HTTPS
和 LDAPS
(话虽如此,即使您的服务不使用HTTP,使用HTTPS
作为端点识别算法也不是一个坏选择,肯定比没有好)。是的。在SSL握手期间,客户端应该将其连接到的主机名与证书中指定的域名进行比较。如果不这样做,TLS就没有用处,因为中间人攻击将变得非常简单。
请注意,存在许多编写不良的软件,它们接受任何呈现的证书并且不进行正确的证书验证。最近有一份关于Android软件的报告涉及到了这个问题。据报道,成千上万的提供的软件标题(主要是免费软件)没有执行正确的验证,从而给用户带来安全风险。