Android上的SSLSocket在证书上没有失败,服务器名称无效

时间:2016-05-22 17:10:34

标签: android ssl

以下是我用于测试SSLSocket针对https://badssl.com返回的SSLCertificateSocketFactory个实例的代码:

SSLCertificateSocketFactory factory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(0);
mSocket = factory.createSocket();
factory.setHostname(mSocket, host);
mSocket.connect(new InetSocketAddress(host, 443), timeout);
mInput = mSocket.getInputStream();
mOutput = mSocket.getOutputStream();

此代码在连接到badssl.com:443时有效,在连接到expired.badssl.com:443self-signed.badssl.com:443时会按预期引发异常,但在连接到{时不会抛出 {1}}。

如果这有所不同,请注意https://badssl.com上的所有主机名似乎共享一个IP,因此需要为SNI配置wrong.host.badssl.com:443

PS:这是在运行Android 6.0.1的Nexus 5上观察到的。

1 个答案:

答案 0 :(得分:1)

TL; TR:根据你的代码,它根本不会检查主机名。

来自documentation of SSLCertificateSocketFactory

  

大多数SSLSocketFactory实现都不验证服务器的身份,允许中间人攻击。此实现确实检查服务器的证书主机名,但仅针对指定主机名的createSocket变体。当使用使用InetAddress的方法或返回未连接套接字的方法时,您必须自己验证服务器的身份以确保安全连接。

因此,如果您使用local_i == 0,它应检查套接字。但如果您使用fcreateSocket(hostname,...),则不会检查名称,因为它不知道要检查的主机名。 createSocket()调用仅用于设置SNI TLS扩展名。