草庐IT

java - 需要帮助了解证书链

coder 2023-09-02 原文

目前我正在编写一个 java 库来访问 pointhq.com 的 REST API。

在开发 Android 客户端时,我意识到默认情况下不接受 SSL 证书,因此我编写了一个自定义 TrustManager 并添加了 pointhq.com 证书,如本文所述:Trusting all certificates using HttpClient over HTTPS

使用此 Trustmanager 和我导入的 bks 文件,我在尝试连接时收到以下错误:IssuerName(CN=GeoTrust Global CA, O=GeoTrust Inc., C=US) does not match SubjectName(CN=RapidSSL CA, O="GeoTrust, Inc.", C=US) 的签名证书。

那我做错了什么?我导入了 pointhq.com、rapidssl.com、geotrust.com 证书。但是什么都没有改变。是否有一种我必须注意的证书分类?我是否缺少根证书?

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

类型:BKS 提供者:卑诗省 条目数:3

条目别名:geotrust global ca 创建日期:19.10.2011 15:44:35 MESZ 类型:可信证书 证书: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) 创建日期:29.09.2011 18:55:12 MESZ 类型:可信证书 证书: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

条目别名:rapidssl ca (geotrust global ca) 创建日期:29.09.2011 18:54:49 MESZ 类型:可信证书 证书: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 连接被接受,有时则不被接受!即使它是我连接到的同一个站点。

https://ssltest12.bbtest.net/ 是我使用的 RapidSSL 证书的演示站点。正如您在 Android 2.1 屏幕截图中看到的那样,第一次连接未被接受,但第二次尝试工作得很好,而最后一次再次失败。怎么会这样?

顺便说一句:自 Android 2.3.3 起,无需任何自定义代码即可接受 RapidSSL 证书!

截图:

最佳答案

是的,链中证书的顺序很重要。基本上,您希望将证书从您的证书订购到 CA。浏览器会为你做这件事,但 Java 不会。我遇到了链中无序证书的问题,最后我编写了一个简单的 X509TrustManager 实现:

    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);

    }
}

注意排序的“while”循环。

关于java - 需要帮助了解证书链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7822381/

有关java - 需要帮助了解证书链的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

  3. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  4. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  5. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  6. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  9. ruby - 为什么在 ruby​​ 中创建 Rational 不需要新方法 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Rubysyntaxquestion:Rational(a,b)andRational.new!(a,b)我正在阅读ruby镐书,我对创建有理数的语法感到困惑。Rational(3,4)*Rational(1,2)产生=>3/8为什么Rational不需要new方法(我还注意到例如我可以在没有new方法的情况下创建字符串)?

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐