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

我在这篇文章中指的是针对CA的Validate X.509证书 。

我的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在打开网站后从浏览器导出。 证书路径看起来像 在此处输入图像描述

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

如果我调试代码然后,在for循环@ LOC cert.verify(Mycert.getPublicKey()); 在第一个cert [0]证书上,我得到exception,因为java.security.SignatureException: Signature does not match.

我在哪里做错了?

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

你需要回顾一下你在这种方法中应该做些什么。 见Javadoc。 您正在尝试建立从此链到受信任根证书的证书路径。

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

你应该做的是:

  1. 链中查找该证书,如果没有找到
  2. 根据此公钥validation链中的最后一个证书,因为这是最顶层的签名者,而且这是您唯一需要信任的证书。 其余的人都被他们在链中的各自成员所信任,他们的inheritance者都不是这个受信任的根证书,(1)。
  3. 如果在链中找到证书,请validation以前的证书。 即由此证书签名的公钥。

我不清楚您是否还需要使用下一个公钥来validation链中的每个证书(除了最后一个证书),但它不会受到伤害。

编辑您还应该在此答案中实施建议。