我有一个需要连接到SSL
服务器的Java应用程序。
该服务器提供了Java cacert
无法自动识别的专有证书。
所以我有两个解决方案:
a)手动导入我的客户java
本地keystore
中的证书(.der,.pem等)
b)实现信任所有证书的信任管理器
基于:
// prepare Verifiers that will accept certificate from ANY host
yesHostnameVerifier = new CYesHostnameVerifier();
// initiate the SSL context and prepare trust manager that will accept ANY certificate
TrustManager yesTrustManager = new CYesTrustManager();
TrustManager[] yesTrustManagers = new TrustManager[] {yesTrustManager};
try {
SSLContext yesSslcontext = SSLContext.getInstance("TLS");
yesSslcontext.init(null, yesTrustManagers, null); // key manager, trust manager, secure random manager
yesSslFactory = yesSslcontext.getSocketFactory();
} catch (Exception e) {
}
// configure the HTTPS connection
HttpsURLConnection.setDefaultSSLSocketFactory(yesSslFactory);
HttpsURLConnection.setDefaultHostnameVerifier(yesHostnameVerifier);
和
public class CYesTrustManager implements X509TrustManager {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
}
和
public class CYesHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
}
在我看来:
相反,我想要的是以编程方式完成所有这些操作:
由于证书无效而引发异常时:
1)从SSL会话中获取服务器证书
2)从此证书中获取主要有用信息并将其显示给用户(通过Swing)
3)询问用户是否接受此证书
4)如果是,请在本地keystore
导入证书
所有这些都是以编程方式。
这样,如果有一天证书被篡改,则至少会向用户显示新消息,从而使其有点怀疑。这与最后的标准ssh会话非常相似。 好主意?坏主意?
有人会为1)2)和4)
提供一些示例代码