在我们的应用程序中,我们正在通过HTTPS对身份验证服务进行HTTP调用。 我需要确保我们进行了所有必要的检查,以确保连接安全。作为它的一部分,我必须实现以下内容:
我对项目1没有任何问题。
对于第2项,我尝试使用HostNameVerifier的实现。
到目前为止,我的代码:
package com.company;
import sun.security.x509.X500Name;
import javax.net.ssl.*;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class Main {
public static void main(String[] args) throws Exception {
URL endpoint = new URL("https://example.com");
HttpsURLConnection conn = (HttpsURLConnection) endpoint.openConnection();
conn.setHostnameVerifier(new MyHostNameVerifier());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] {trustAll}, null);
conn.setSSLSocketFactory(sslContext.getSocketFactory());
System.out.println("HTTP Response: " + conn.getResponseCode());
}
public static final X509TrustManager trustAll = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates,
String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates,
String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
public static class MyHostNameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostName, SSLSession sslSession) {
System.out.println("*** Validating host name for " + hostName);
return false;
}
}
}
我期望MyHostNameVerifier#verify
将始终被调用,我可以在那里进行某些检查。
但是,我发现仅当我使用站点的IP地址或仅当主机名与证书主题或任何主题备用名称不匹配时,才会调用HostNameVerifier#verify
方法。
HostNameVerifier#verify
:
例如:
在上面的代码中,我试图连接到“ example.com”。
SSL证书“ example.com”已颁发给CN“ www.example.org”。
但是,证书的“主题备用名称”(SAN)中列出了“ example.com”。
如果我改用IP地址“ example.com”,则将调用我的主机名验证程序。
URL endpoint = new URL("https://93.184.216.34/");
有人可以向我确认Java在内部处理通配符证书和SAN证书检查吗?如果是,那么,我可能不必进行任何其他代码更改。
答案 0 :(得分:0)
在引用Java documentation的情况下,我可能会走出一些界限,但这是我们最纯正的消息来源。
在握手过程中,如果URL的主机名和服务器的标识主机名不匹配,则验证机制可以回调此接口的实现者,以确定是否应允许此连接。
当URL主机名验证的默认规则失败时,将使用这些回调。
从根本上确认您的观察,即一旦输入无效证书,它将随后(仅然后)调用该函数以查看是否仍要允许它。通过您自己的测试(正确的通配符证书未调用该函数),我们可以说他已明确确认该函数有效,并且不需要您的帮助。 SAN证书也是如此。