首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XAdES BES时间戳验证错误

XAdES BES时间戳验证错误
EN

Stack Overflow用户
提问于 2014-03-23 16:09:16
回答 1查看 2.2K关注 0票数 0

我试图使用xades4j库进行验证,该库使用赏金城堡进行Xades,并得到以下堆栈跟踪:

代码语言:javascript
复制
xades4j.verification.TimeStampInvalidSignatureException: Verification failed for property     'SignatureTimeStamp': invalid token signature
    at xades4j.verification.TimeStampVerifierBase.getEx(TimeStampVerifierBase.java:114)
    at xades4j.verification.TimeStampVerifierBase.verify(TimeStampVerifierBase.java:89)
    at xades4j.verification.TimeStampVerifierBase.verify(TimeStampVerifierBase.java:38)
    at xades4j.verification.QualifyingPropertiesVerifierImpl.verifyProperties(QualifyingPropertiesVerifierImpl.java:59)
    at xades4j.verification.XadesVerifierImpl.getValidationDate(XadesVerifierImpl.java:250)
    at xades4j.verification.XadesVerifierImpl.verify(XadesVerifierImpl.java:174)
    at com.signapplet.sign.SignComponent.verify(SignComponent.java:663)


Caused by: xades4j.providers.TimeStampTokenSignatureException: Invalid token signature or certificate
    at xades4j.providers.impl.DefaultTimeStampVerificationProvider.verifyToken(DefaultTimeStampVerificationProvider.java:154)
    at xades4j.verification.TimeStampVerifierBase.verify(TimeStampVerifierBase.java:71)
    ... 42 more
Caused by: org.bouncycastle.tsp.TSPValidationException: certificate hash does not match certID hash.
    at org.bouncycastle.tsp.TimeStampToken.validate(Unknown Source)
    at xades4j.providers.impl.DefaultTimeStampVerificationProvider.verifyToken(DefaultTimeStampVerificationProvider.java:150)
    ... 43 more

下面是xades4j中抛出异常的代码:

代码语言:javascript
复制
try
{
    tsToken.validate(this.signerInfoVerifierBuilder.build(tsaCert)); //tsToken==org.bouncycastle.tsp.TimeStampToken
}
catch (TSPValidationException ex)
{
    throw new TimeStampTokenSignatureException("Invalid token signature or certificate", ex);
}
catch (Exception ex)
{
    throw new TimeStampTokenVerificationException("Error when verifying the token signature", ex);
}

只有当我用加密令牌制造商提供的软件对文件进行签名时,才会出现这个问题。顺便说一下,该软件到目前为止工作得很好,而且我能够用不同的验证软件验证同一个文件。这个问题只发生在xades4j中。

当我用xades4j对同一个文件签名时,它将验证所有预期的内容。

下面是验证代码。certDataList是一个包含来自文档的所有证书的列表,getCert将返回列表。DummyCertificateValidationProvider返回带有先前构造的x509certs的列表的ValidationData。

代码语言:javascript
复制
    public boolean verify(final File file) {
        if (!Dictionaries.valid()) {
            return true;
        }
        certList = null;
        try {

            final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            final DocumentBuilder db = dbf.newDocumentBuilder();

            final Document doc = db.parse(file);
            doc.getDocumentElement().normalize();

            final NodeList nList = doc.getElementsByTagName("ds:Signature");
            Element elem = null;
            for (int temp = 0; temp < nList.getLength(); temp++) {
                final Node nNode = nList.item(temp);
                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                    elem = (Element) nNode;
                }
            }
            final NodeList nList2 = doc.getElementsByTagName("ds:X509Certificate");
            final List<String> certDataList = new ArrayList<String>();
            for (int temp = 0; temp < nList2.getLength(); temp++) {
                final Node nNode = nList2.item(temp);
                certDataList.add(nNode.getTextContent());
            }
            certList = getCert(certDataList);

            final CertificateValidationProvider certValidator = new DummyCertificateValidationProvider(certList);

            final XadesVerificationProfile p = new XadesVerificationProfile(certValidator);
            final XadesVerifier v = p.newVerifier();
            final SignatureSpecificVerificationOptions opts = new SignatureSpecificVerificationOptions();

            // for relative document paths
            final String baseUri = "file:///" + file.getParentFile().getAbsolutePath().replace("\\", "/") + "/";
            LOGGER.debug("baseUri:" + baseUri);
            opts.useBaseUri(baseUri);
            v.verify(elem, opts);
            return true;
        } catch (final IllegalArgumentException | XAdES4jException | CertificateException | IOException | ParserConfigurationException | SAXException e) {
            LOGGER.error("XML not validated!", e);
        }

        return false;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-26 21:02:51

CertificateValidationProvider必须返回包含证书链的ValidationData,该证书链验证由所提供的CertSelector表示的证书。作为在文档中描述ValidationData上的证书应该是有序的,即第一个证书应该是签名证书。

验证TS令牌时,签名证书是TSA的证书。当要求CertificateValidationProvider使用CertSelector进行验证时,它必须在链的第一个位置返回TSA证书。如前所述,TS验证代码将假定它处于第一个位置。

在您的验证代码中,您将选择签名中的所有证书。该列表不是所有所需证书验证的有效证书链。最终,TSA证书甚至不会出现在签名上。

我认为您需要将CertificateValidationProvider实现更改为在第一个位置返回适当的证书。如果这有帮助的话请告诉我。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22593399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档