首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >证书链中的SSLHandshakeException行为

证书链中的SSLHandshakeException行为
EN

Stack Overflow用户
提问于 2016-10-12 13:14:46
回答 1查看 276关注 0票数 1

我使用此证书链的存储证书实现了证书钉扎:

  • 证书1:云平台
  • 证书2: Verizon (中级CA)
  • 证书3:巴尔的摩(根CA)

不过,我注意到一种奇怪的行为:

  • 行为1(预期):如果我只固定证书1,我将得到一个SSLHandshakeException错误,因为我需要在链中包含所有证书。
  • 行为2(意外?):如果我只将证书2(中间CA )固定在一起,我就不会得到任何SSLHandshakeException错误。

你会知道行为2是否被期望,如果是,为什么?我的印象是,链中的所有证书都应该使用,否则我会得到一个SSLHandshakeException。谢谢!

更新为代码

代码语言:javascript
复制
class SSLPinning {

void exec() {

    // Open InputStreams for each certificate
    InputStream baltimoreInputStream = getClass().getResourceAsStream("baltimore.cer");
    InputStream hcpmsInputStream = getClass().getResourceAsStream("hcpms_cert.cer");
    InputStream verizonInputStream = getClass().getResourceAsStream("verizon.cer");

    try {

        // CertificateFactory has the method that generates certificates from InputStream
        // Default type for getInstance is X.509
        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        // Create Certificate objects for each certificate
        Certificate baltimoreCertificate = cf.generateCertificate(baltimoreInputStream);
        Certificate hcpmsCertificate = cf.generateCertificate(hcpmsInputStream);
        Certificate verizonCertificate = cf.generateCertificate(verizonInputStream);

        // Create KeyStore and load it with our certificates
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        //keyStore.setCertificateEntry("hcpms", hcpmsCertificate);
        keyStore.setCertificateEntry("intermediate", verizonCertificate); //surprisingly, it works with just using the intermediate CA
        //keyStore.setCertificateEntry("root", baltimoreCertificate);

        // Create a TrustManagerFactory using KeyStore -- this is responsible in authenticating the servers
        // against our stored certificates
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);

        // Create an SSLContext using TrustManagerFactory -- this will generate the SSLSocketFactory we will use
        // during HTTPS connection
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);

        URL url = new URL("https://account.hanatrial.ondemand.com/");
        HttpsURLConnection httpsURLConnection = (HttpsURLConnection)url.openConnection();
        httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
        httpsURLConnection.connect();
        System.out.print("Server authentication successful");

    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (CertificateException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (SSLHandshakeException e) {
        System.out.println("Server authentication failed");
    } catch (IOException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }

}

}

EN

回答 1

Stack Overflow用户

发布于 2016-10-12 15:05:52

您的主要问题是,要验证证书,必须存在可信链(信任证书和所有到服务器/叶证书为止的中间证书)。但是,大多数SSL/TLS服务器不会向您发送完整的链。有时您只获得叶证书(没有中间证书或根证书;您可以在Wireshark流量转储中看到这一点)。

其他服务器可以向您发送叶证书和所有/一些中间证书,但不发送根证书。

在这种情况下,本地信任库包含缺失的证书对于构建完整的链至关重要。

根据您的观察,我假设服务器只发送叶证书,而不发送中间证书和根证书。因此,要进行成功的验证,您的信任库必须将中间证书作为受信任的证书,才能使其工作(否则该证书将丢失)。我建议将根证书和中间证书包含到您的信任库中。

不发送中间CA证书的服务器也可能是服务器配置问题。通常,我建议将服务器配置为发送叶证书和中间证书。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39999559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档