检查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 CERTIFICATE
和END CERTIFICATE
是他们的证书链。
如果我调试代码然后,在for
循环@ LOC cert.verify(Mycert.getPublicKey());
在第一个cert [0]证书上,我得到exception,因为java.security.SignatureException: Signature does not match.
我在哪里做错了?
尝试针对单个公钥validation链中的所有证书是没有意义的。 它们中的大多数都不会被它签名,因此该过程必然会失败,并向调用者抛出exception。
你需要回顾一下你在这种方法中应该做些什么。 见Javadoc。 您正在尝试建立从此链到受信任根证书的证书路径。
在这种情况下,受信任的根证书可能是您从文件加载的证书。
你应该做的是:
- 在链中查找该证书,如果没有找到
- 根据此公钥validation链中的最后一个证书,因为这是最顶层的签名者,而且这是您唯一需要信任的证书。 其余的人都被他们在链中的各自成员所信任,他们的inheritance者都不是这个受信任的根证书,(1)。
- 如果在链中找到证书,请validation以前的证书。 即由此证书签名的公钥。
我不清楚您是否还需要使用下一个公钥来validation链中的每个证书(除了最后一个证书),但它不会受到伤害。
编辑您还应该在此答案中实施建议。