本文介绍了需要帮助理解证书链的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在写一个Java库访问pointhq.com的REST API。

At the moment I am writing a java library to access the REST API of pointhq.com.

在开发我意识到,SSL证书不被接受默认情况下,Android客户端,所以我写了一个定制的TrustManager,并且增加了pointhq.com证书在这篇文章中解释一样:Trusting使用HttpClient的所有证书通过HTTPS

While developing a Android client I realized that the SSL certificate is not accepted by default so I wrote a custom TrustManager and added the pointhq.com certificate like explained in this post: Trusting all certificates using HttpClient over HTTPS

使用这个的TrustManager和我进口BKS文件,我得到以下错误,同时试图连接:证书中issuerName(CN = GeoTrust的全球CA,O = GeoTrust的公司,C = US)不匹配SubjectName( CN =的RapidSSL CA,O =GeoTrust的公司,C =的签名证书美国)。

Using this Trustmanager and my imported bks file I get the following error while trying to connect: IssuerName(CN=GeoTrust Global CA, O=GeoTrust Inc., C=US) does not match SubjectName(CN=RapidSSL CA, O="GeoTrust, Inc.", C=US) of signing certificate.

所以我做了什么错?我进口pointhq.com,rapidssl.com,geotrust.com证书。但什么都没有改变。有没有一种证书,我必须要知道的排序?我缺少一个根证书?

So what did I do wrong? I imported the pointhq.com, rapidssl.com, geotrust.com certificates. But nothing changed. Is there a kind of sorting of certificates I have to be aware of? Am I missing a root certificate?

编辑:这是导入的证书的列表:

Here is the list of imported certificates:

类型:BKS提供者:BC参赛作品:3

Type: BKSProvider: BCEntries: 3

输入别名:GeoTrust的全球CA创建日期:19.10.2011十五时44分35秒MESZ类型:可信证书证书:1

Entry Alias: geotrust global caCreation Date: 19.10.2011 15:44:35 MESZType: Trusted CertificateCertificates: 1

Certificate 1 of 1
Version: 3
Subject: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
Issuer: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
Serial Number: 0002 3456
Valid From: 21.05.2002 06:00:00
Valid Until: 21.05.2022 06:00:00
Public Key: RSA (2.048 bits)
Signature Algorithm: SHA1withRSA
SHA-1 Fingerprint: DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12
MD5 Fingerprint: F7:75:AB:29:FB:51:4E:B7:77:5E:FF:05:3C:99:8E:F5

输入别名:pointhq.com(的RapidSSL CA)创建日期:2011年9月29日18点55分12秒MESZ类型:可信证书证书:1

Entry Alias: pointhq.com (rapidssl ca)Creation Date: 29.09.2011 18:55:12 MESZType: Trusted CertificateCertificates: 1

Certificate 1 of 1
Version: 3
Subject: CN=pointhq.com, OU=Domain Control Validated - RapidSSL(R), OU=See www.rapidssl.com/resources/cps (c)11, OU=GT70151377, O=pointhq.com, C=GB, SERIALNUMBER=8Dvj7qRSYLjGZiX2tHocE2FDaqAp8RwO
Issuer: CN=RapidSSL CA, O="GeoTrust, Inc.", C=US
Serial Number: 8971
Valid From: 31.01.2011 13:20:09
Valid Until: 03.02.2013 09:15:38
Public Key: RSA (2.048 bits)
Signature Algorithm: SHA1withRSA
SHA-1 Fingerprint: BB:04:D0:3E:1A:36:02:F7:C3:8C:85:99:1D:67:2A:6B:CF:C1:BC:C5
MD5 Fingerprint: 21:9D:DF:72:E6:4A:33:47:E1:BA:D6:52:86:1E:59:B4

输入别名:CA的RapidSSL(GeoTrust的全球CA)创建日期:2011年9月29日18时54分49秒MESZ类型:可信证书证书:1

Entry Alias: rapidssl ca (geotrust global ca)Creation Date: 29.09.2011 18:54:49 MESZType: Trusted CertificateCertificates: 1

Certificate 1 of 1
Version: 3
Subject: CN=RapidSSL CA, O="GeoTrust, Inc.", C=US
Issuer: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
Serial Number: 0002 36D1
Valid From: 19.02.2010 23:45:05
Valid Until: 18.02.2020 23:45:05
Public Key: RSA (2.048 bits)
Signature Algorithm: SHA1withRSA
SHA-1 Fingerprint: C0:39:A3:26:9E:E4:B8:E8:2D:00:C5:3F:A7:97:B5:A1:9E:83:6F:47
MD5 Fingerprint: 1B:EE:28:5E:8F:F8:08:5F:79:CC:60:8B:92:99:A4:53

我现在写了一个SSL测试应用程序。结果是令人困惑的。正如你所连接的截图看,有时SSL连接被接受,有些时候它不是!即使是我连接到同一个站点。

I now wrote an SSL Test app. The results are confusing.As you can see on the attached screenshots, sometimes the ssl connection is accepted and some times its not! Even if it is the same site that I'm connecting to.

https://ssltest12.bbtest.net/ 是演示站点为的RapidSSL证书我用什么。正如你可以在Android 2.1的截图中看到的第一个连接获得的不被接受的,但第二次尝试工作完全正常,而最后不能再工作。如何发生的呢?

https://ssltest12.bbtest.net/ is the demo site for the RapidSSL certificate I what to use. As you can see on the Android 2.1 Screenshot the first connection get's not accepted the but the second try works perfectly fine, while the last doesn't work again. How can that happen?

BTW:由于Android 2.3.3的RapidSSL证书是不接受任何自定义code

BTW: Since Android 2.3.3 the RapidSSL certificate is accepted without any custom code!

Scrennshots:

Scrennshots:

  • http://jcodehq.org/Android2.1.png
  • http://jcodehq.org/Android2.2.png
  • http://jcodehq.org/Android2.3.3.png
  • http://jcodehq.org/Android4.0.png

推荐答案

是的,在链物质证书的顺序。基本上你想要的证书从你到CA. odered浏览器为你做它,但Java则没有。我有问题,在链无序的证书,我结束了写一个简单的实现X509TrustManager用:

Yes, the order of certificates in chain matter. Basically you want certificates to be odered from yours to CA. Browsers do it for you, but Java does not. I had the issue with unordered certificates in chain and I ended up writing a simple implementation of X509TrustManager with:

    public void checkServerTrusted(X509Certificate[] certificates,String authType) throws CertificateException {
    if ((certificates != null) && LOG.isDebugEnabled()) {
        LOG.debug("Server certificate chain:");
        for (int i = 0; i < certificates.length; i++) {
            LOG.debug("X509Certificate[" + i + "]=" + certificates[i]);
        }
    }
    if ((certificates != null) && (certificates.length == 1)) {
        certificates[0].checkValidity();
    } else {
        List<X509Certificate> certs = new ArrayList<X509Certificate>();
        certs.addAll(Arrays.asList(certificates));
        X509Certificate certChain = certs.get(0);
        certs.remove(certChain);
        LinkedList<X509Certificate> chainList= new LinkedList<X509Certificate>();
        chainList.add(certChain);
        Principal certIssuer = certChain.getIssuerDN();
        Principal certSubject = certChain.getSubjectDN();
        while(!certs.isEmpty()){
            List<X509Certificate> tempcerts = new ArrayList<X509Certificate>();
            tempcerts.addAll(certs);
            for (X509Certificate cert : tempcerts){
                if(cert.getIssuerDN().equals(certSubject)){
                    chainList.addFirst(cert);
                    certSubject = cert.getSubjectDN();
                    certs.remove(cert);
                    continue;
                }

                if(cert.getSubjectDN().equals(certIssuer)){
                    chainList.addLast(cert);
                    certIssuer = cert.getIssuerDN();
                    certs.remove(cert);
                    continue;
                }
            }
        }
    standardTrustManager.checkServerTrusted(chainList.toArray(new X509Certificate[]{}),authType);

    }
}

注意顺序,而循环。

Notice the ordering "while" cycle.

这篇关于需要帮助理解证书链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-27 21:22