Java代码连接SSL服务器时,JVM需要验证服务器时可信任的。否则你会遇到如下的Exception。
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
SUN提供了若干工具来导入证书,可惜都很繁琐。我在网上找到一个牛人写的程序,可以将指定Server:Port的SSL证书自动导入到JVM的信任列表中。但是该程序并不容易理解,因此我将我的研究结果写了出来。在该程序中,生成证书的过程如下:
1. 找到jre/lib/security/cacerts文件,将其load到一个Java.security.KeyStore中。
2. 获取一个SSLContext的实例,它负责生成SSL Socket的工厂;
3. 生成一个TrustManagerFactory的实例,它负责根据“信任材料源”(来自KeyStore中)生成TrustManager。
4. 获取一个TrustManager,此处为X509TrustManager,基于该实例,创建SavingTrustManager
5. 利用SSLContext初始化TrustManager,此时TrustManager就会注册到SSLSocket中;
6. 利用SSLContext获得SSLSocketFactory并创建到目的端口的SSL Socket连接;
7. TrustManager会获得一个X509Certificate的数组;
8. 将其中的一个Certificate加入到KeyStore中去;
9. 保存KeyStore。
KeyStore
这是一个保存Key的类,它负责读写Key文件。这个文件中包含3类的条目:
1. KeyStore.PrivateKeyEntry:这是为了发布一个Entity而使用的,如果你要发布一个Jar,又想别人放心的使用它,就的使用这个entry,当然客户端需要信任你的Certificate才能使用它;
2. KeyStore.SecretKeyEntry:
3. KeyStore.TrustedCertificateEntry:这是和第一种相对应的,如果你要访问一个别人的SSL端口,为了确保你连的是X而不是Y,你需要将X的证书放在这里,而不是将Y的放在这里;
TrustManagerFactory
它首先装在KeyStore,然后它可以用来验证远端的Server是否是可信任的。根据不同的算法,它可以返回不同的TrustManager,它们依赖于不同的算法进行验证。当客户端通过SSL Socket连接到Server时,它会请求TrustManager验证这个远端的Server。这里用到了回调的方法,TrustManager的以下方法会被调用到:
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
其中输入的X509Certificate数组来自于远端的Server,于是,我们就得到了很重要的东西。
接下来的工作就是将得到的Certificate存成可信任的,也就是作为KeyStore.TrustedCertificateEntry存到KeyStore中。以后当你要访问这个网站的时候,你就不会遇到文章开始时提到的Exception了。
本文介绍了一种自动将指定Server的SSL证书导入JVM信任列表的方法。通过详细步骤解析,帮助读者理解证书导入过程及原理。
1053





