如何建立对中间人颁发的X.509证书的信任?

时间:2011-01-14 21:28:34

标签: java security

我有一个经过数字签名的XML文档。我使用XML Digital Signature API来验证签名。但是,此文档是SAML 2.0断言,将用于单点登录到我们的Web应用程序。因此,我需要建立对用于签署XML文档的X.509证书的信任。

我用来尝试建立这种信任的代码是:

String filename = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar);
FileInputStream is = new FileInputStream(filename);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
String password = "changeit";
keystore.load(is, password.toCharArray());

PKIXParameters params = new PKIXParameters(keystore);
params.setRevocationEnabled(false);

CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
CertPath certPath = certFactory.generateCertPath(Arrays.asList(signatureCertificate));

CertPathValidator certPathValidator = CertPathValidator.getInstance(CertPathValidator.getDefaultType());
CertPathValidatorResult result = certPathValidator.validate(certPath, params);

PKIXCertPathValidatorResult pkixResult = (PKIXCertPathValidatorResult) result;
TrustAnchor ta = pkixResult.getTrustAnchor();
X509Certificate cert = ta.getTrustedCert();

运行certPathValidator.validate()时,CertPathValidatorException会发送Path does not chain with any of the trust anchors消息{。}}。

检查证书时,它表示已由OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign,OU=VeriSign International Server CA - Class 3,OU=VeriSign\, Inc.,O=VeriSign Trust Network发出。 这不是JDK cacerts密钥库中的信任锚之一。

但是,使用IE来检查类似证书的信任链,我发现www.verisign.com/CPS Incorp.是由VeriSign Class 3 Public Primary CA发出的,{{1}}似乎是JDK的cacerts密钥库中的信任锚之一。

我的问题:如何让Java验证此证书?

3 个答案:

答案 0 :(得分:4)

将颁发CA的公共证书插入到cacert密钥库中。

编辑:您可以使用keytool或其他工具之一。文章描述了keytool的使用:keytool-Key and Certificate Management Tool

答案 1 :(得分:3)

正是xelco所说的 - 添加中间CA:

OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign,OU=VeriSign International Server CA - Class 3,OU=VeriSign\, Inc.,O=VeriSign Trust Network

到JDK的密钥库。您可以使用keytool来完成它。

原因:通常在签署XML消息时,签名仅包含签名证书。 X509证书就像单链表。最终实体指向其发行人。发行人指向其发行人,直到您找到指向自身的自签名根CA.要根据PKIX验证证书,验证程序需要能够构建从最终实体到自签名根的整个CA链,因此链的每个部分(最终实体除外)都必须位于证书存储区中。

答案 2 :(得分:-1)

我有更好的解决方案。我找到了可以运行的java服务并为我们做了一切。

爪哇: http://code.google.com/p/java-use-examples/source/browse/trunk/src/com/aw/ad/util/InstallCert.java