使用Java编写SSL检查器
有人知道关于用Java编写SSL检查器的好教程、网站和/或书籍吗?我正在尝试做什么可以在这里找到:。使用Java编写SSL检查器,java,ssl,x509,Java,Ssl,X509,有人知道关于用Java编写SSL检查器的好教程、网站和/或书籍吗?我正在尝试做什么可以在这里找到:。 我不是在尝试创建自签名证书或使用密钥库。我希望能够访问任何站点,确定是否存在有效的SSL证书,确定证书上的主机名是否与输入的名称匹配,并确定此证书何时过期。我在谷歌上搜索过这个主题,但“如何使用Java创建SSL购物者”并没有给我带来任何结果,我的其他搜索只给我提供了如何创建自签名证书的链接。任何帮助都将不胜感激。您可以做的是在e.g 您应该初始化SSL上下文,并覆盖TrustManagers,
我不是在尝试创建自签名证书或使用密钥库。我希望能够访问任何站点,确定是否存在有效的SSL证书,确定证书上的主机名是否与输入的名称匹配,并确定此证书何时过期。我在谷歌上搜索过这个主题,但“如何使用Java创建SSL购物者”并没有给我带来任何结果,我的其他搜索只给我提供了如何创建自签名证书的链接。任何帮助都将不胜感激。您可以做的是在e.g
您应该初始化SSL上下文,并覆盖
TrustManagers
,以执行所需的任何检查
主机名验证可以由库自动完成
例如,以下将配置SSL套接字处理,以便在主机名与证书信息不匹配时引发异常:
SSLSocketFactory sf = new SSLSocketFactory(
SSLContext.getInstance("TLS"),
SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
要首先获取服务器证书以便手动执行验证,不管它是否有效,最简单的方法是在禁用任何证书验证后通过
SSLSocket
进行连接
创建允许任何内容通过的SSLContext
:
SSLContext sslContext = SSLContext.getInstance("TLS");
X509TrustManager passthroughTrustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] { passthroughTrustManager },
null);
(旁注:对于正在寻找内部使用测试证书的方法的人,我建议您构建自己的测试CA,而不是禁用检查,以防这些虚拟检查错误地遗留在生产代码中,并且因为这使测试更加真实。)
创建一个套接字,连接并显式启动握手(因为您实际上不打算从中读取):
获取对等证书链。第一项是实际的服务器证书
X509Certificate[] peerCertificates = (X509Certificate[]) socket
.getSession().getPeerCertificates();
如果要根据默认信任锚(默认的受信任CA证书)进行验证,请基于默认值构建X509TrustManager
(这实际上是上面禁用的passthroughTrustManager
):
现在,检查证书当前是否及时有效,是否根据受信任的锚进行了验证,以及它是否具有正确的扩展
所有这些都利用了
或者,如果您想深入了解PKIX的详细信息,可以使用(JSSE使用)
(如果您只希望从有效证书开始,只需在开始时使用SSLContext SSLContext=SSLContext.getDefault()
,创建套接字并进行握手。)
要直接获取服务器证书,可以使用以下方法:
X509Certificate serverCert = peerCertificates[0];
有许多关于日期和各种扩展的方法。例如:
Date expirationDate = serverCert.getNotAfter();
主机名验证应遵循(或至少遵循)。简言之,检查您要连接的主机名是否是Subject Alternative Names(SAN)DNS条目之一。如果做不到这一点,请回头检查主机名是否在证书的CN RDN中(为此,需要将主题DN拆分为RDN)。你也可能对这一点感兴趣
这完全取决于你想进行多少“手动”验证。除API文件外,还有许多规范需要阅读(至少RFC 5280/RFC 3280和RFC 6125/RFC 2818)
关于Security.SE的这个问题也应该引起关注:
try {
// Assuming RSA key here.
tm.checkServerTrusted(peerCertificates, "RSA");
} catch (CertificateException e) {
// Here you may check which subclass of CertificateException to know what the error is.
}
X509Certificate serverCert = peerCertificates[0];
Date expirationDate = serverCert.getNotAfter();