检查checkServerTrusted中的服务器证书的问题

时间:2015-01-28 14:48:14

标签: java x509certificate

我指的是Validate X.509 certificate against CA in Java这篇文章。

checkServerTrusted的实现如下:

@Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) throws  CertificateException{
                 InputStream inStream;
                try {
                        inStream = new FileInputStream("E:\\Desktop\\cert\\domain.crt");
                        CertificateFactory cf = CertificateFactory.getInstance("X.509");
                        X509Certificate Mycert = (X509Certificate)cf.generateCertificate(inStream);
                        inStream.close();      

                        if (certs == null || certs.length == 0 || authType == null
                                || authType.length() == 0) {
                            throw new IllegalArgumentException("null or zero-length parameter");
                        }

                         for (X509Certificate cert : certs) {
                             cert.verify(Mycert.getPublicKey());
                         }


                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    throw new CertificateException("error in validating certificate" , e);
                }

            }

文件domain.crt在打开网站后从浏览器导出。证书路径看起来像enter image description here

如果我在记事本中打开此文件,则只有一个BEGIN CERTIFICATEEND CERTIFICATE是他们的证书链。

如果我调试代码,那么在第一个cert [0]证书的for循环@LOC cert.verify(Mycert.getPublicKey());中我得到例外java.security.SignatureException: Signature does not match.

我做错了什么?

1 个答案:

答案 0 :(得分:0)

尝试针对单个公钥验证链中的所有证书是没有意义的。它们中的大多数都不会被它签名,因此该过程必然会失败,并向调用者抛出异常。

您需要查看此方法中您应该做的事情。见Javadoc。您正在尝试建立从此链到受信任的根证书的证书路径。

在这种情况下,受信任的根证书可能是您从文件中加载的证书。

你应该做的是:

  1. 在链中找到该证书,如果没有找到
  2. 根据此公钥验证链中的 last 证书,因为这是最顶层的签名者,而且这是您唯一需要信任的证书。其余的人都被他们各自的成员所信任,并且他们的继承者都不是这个受信任的根证书,(1)。
  3. 如果在链中找到证书 ,请验证以前的证书。即使用此公钥签署的证书。
  4. 我不清楚您是否还需要使用下一个公钥验证链中的每个证书(除了最后一个证书),但它不会受到伤害。

    编辑您还应该在this answer中实施建议。