使用未经认证的证书进行SSL连接 - 如何以编程方式导入

时间:2015-05-07 09:47:56

标签: java swing security ssl https

我有一个需要连接到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;
    }
}

在我看来:

  • a)是不可能的,因为我不能强迫所有客户手动 那样做
  • b)在生产环境中完全不安全,容易受到中间人攻击,所以,我不想接受所有证书

相反,我想要的是以编程方式完成所有这些操作: 由于证书无效而引发异常时: 1)从SSL会话中获取服务器证书 2)从此证书中获取主要有用信息并将其显示给用户(通过Swing) 3)询问用户是否接受此证书 4)如果是,请在本地keystore导入证书 所有这些都是以编程方式。

这样,如果有一天证书被篡改,则至少会向用户显示新消息,从而使其有点怀疑。这与最后的标准ssh会话非常相似。 好主意?坏主意?

有人会为1)2)和4)

提供一些示例代码

0 个答案:

没有答案