Java 使用XADES4j验证XADES签名

Java 使用XADES4j验证XADES签名,java,xades4j,Java,Xades4j,我们想创建一个JavaWeb应用程序来验证“XADES”签名,这个应用程序应该包含两个文件:原始文件和他的分离签名 我正在使用XADES4j库,这是一个很棒的项目。使用XADES4j,有没有一种方法可以在不验证URI文件引用的情况下验证签名?因为xml签名中的给定引用文件无法访问 参考验证:我希望比较从给定原始文件计算的摘要值和从签名文件提取的摘要值 这是个例外 Exception in thread "main" xades4j.XAdES4jXMLSigException: Error ve

我们想创建一个JavaWeb应用程序来验证“XADES”签名,这个应用程序应该包含两个文件:原始文件和他的分离签名

我正在使用XADES4j库,这是一个很棒的项目。使用XADES4j,有没有一种方法可以在不验证URI文件引用的情况下验证签名?因为xml签名中的给定引用文件无法访问

参考验证:我希望比较从给定原始文件计算的摘要值和从签名文件提取的摘要值

这是个例外

Exception in thread "main" xades4j.XAdES4jXMLSigException: Error verifying the signature
    at xades4j.verification.XadesVerifierImpl.doCoreVerification(XadesVerifierImpl.java:285)
    at xades4j.verification.XadesVerifierImpl.verify(XadesVerifierImpl.java:188)
    at com.wct.VerifyXades.main(VerifyXades.java:33)
Caused by: org.apache.xml.security.signature.MissingResourceFailureException: The Reference for URI file:/D:/workspace/xades4j-487d7a9bb9e5/data_to_sign/test.txt has no XMLSignatureInput
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: D:\workspace\xades4j-487d7a9bb9e5\data_to_sign\test.txt (Le fichier spécifié est introuvable)
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: D:\workspace\xades4j-487d7a9bb9e5\data_to_sign\test.txt (Le fichier spécifié est introuvable)
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: D:\workspace\xades4j-487d7a9bb9e5\data_to_sign\test.txt (Le fichier spécifié est introuvable)
Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: D:\workspace\xades4j-487d7a9bb9e5\data_to_sign\test.txt (Le fichier spécifié est introuvable)
Original Exception was java.io.FileNotFoundException: D:\workspace\xades4j-487d7a9bb9e5\data_to_sign\test.txt (Le fichier spécifié est introuvable)
    at org.apache.xml.security.signature.Manifest.verifyReferences(Manifest.java:412)
    at org.apache.xml.security.signature.SignedInfo.verify(SignedInfo.java:256)
    at org.apache.xml.security.signature.XMLSignature.checkSignatureValue(XMLSignature.java:764)
    at org.apache.xml.security.signature.XMLSignature.checkSignatureValue(XMLSignature.java:696)
    at xades4j.verification.XadesVerifierImpl.doCoreVerification(XadesVerifierImpl.java:278)
    ... 2 more
以下是我用来验证XADES签名的源代码:

package com.wct;

import java.io.FileInputStream;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import xades4j.providers.CertificateValidationException;
import xades4j.providers.CertificateValidationProvider;
import xades4j.providers.ValidationData;
import xades4j.verification.UnexpectedJCAException;
import xades4j.verification.XAdESVerificationResult;
import xades4j.verification.XadesVerificationProfile;
import xades4j.verification.XadesVerifier;

public class VerifyXades {

    public static void main(String[] args) throws Exception {
        CertificateValidationProvider certValidator = new CertificateValidationProviderImpl();
        XadesVerificationProfile p = new XadesVerificationProfile(certValidator);
        p.acceptUnknownProperties(true);
        XadesVerifier v = p.newVerifier();
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(new FileInputStream("data_signed/detachedTestSignature.xml"));
        XAdESVerificationResult vr = v.verify(doc.getDocumentElement(), null);
    }
}

class CertificateValidationProviderImpl implements CertificateValidationProvider {
    @Override
    public ValidationData validate(X509CertSelector certSelector,
            Date validationDate, Collection<X509Certificate> otherCerts)
            throws CertificateValidationException, UnexpectedJCAException {
        return new ValidationData((List<X509Certificate>) otherCerts);
    }
}
package com.wct;
导入java.io.FileInputStream;
导入java.security.cert.X509CertSelector;
导入java.security.cert.x509证书;
导入java.util.Collection;
导入java.util.Date;
导入java.util.List;
导入javax.xml.parsers.DocumentBuilder;
导入javax.xml.parsers.DocumentBuilderFactory;
导入org.w3c.dom.Document;
导入xades4j.providers.CertificateValidationException;
导入xades4j.providers.CertificateValidationProvider;
导入xades4j.providers.ValidationData;
导入xades4j.verification.Unexpected JCAEException;
导入xades4j.verification.XAdESVerificationResult;
导入xades4j.verification.XadesVerificationProfile;
导入xades4j.verification.XadesVerifier;
公共类VerifyXades{
公共静态void main(字符串[]args)引发异常{
CertificateValidationProvider certValidator=新的CertificateValidationProviderImpl();
XadesVerificationProfile p=新的XadesVerificationProfile(certValidator);
p、 接受未知属性(真);
XadesVerifier v=p.newVerifier();
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db=dbf.newDocumentBuilder();
Document doc=db.parse(新文件输入流(“data_signed/detachedTestSignature.xml”);
XAdESVerificationResult vr=v.verify(doc.getDocumentElement(),null);
}
}
类CertificateValidationProviderImpl实现CertificateValidationProvider{
@凌驾
公共验证数据验证(X509CertSelector certSelector,
日期验证日期,收集其他证书)
引发CertificateValidationException,意外JCAEException{
返回新的ValidationData((列出)其他证书);
}
}
我是新的签名/验证开发人员,没有良好的经验。请帮忙


提前感谢您的帮助

您不应该做任何摘要比较。文件必须能够以某种方式访问,以便在签名验证过程中检查引用

您是否控制签名生成?如果是这样,您应该更改相对URI的URI,或者使用匿名引用(更多信息见下文)。无论如何,您的所有选择都将基于

如果您可以更改签名验证:

  • 在引用上使用相对文件uri,并在签名和签名上指定基本uri。有一些关于xades4j测试的例子
  • 使用匿名引用(无URI属性),并使用生成上的签名和上的相应输入指定数据
如果您无法更改签名制作:

  • 它处理文件URI并从中返回文件数据。已经有了(由xades4j使用),但自定义解析器具有优先权。这是一种变通办法。。拥有这些绝对文件URI签名很可能会不断导致您遇到的问题

在我们的情况下,我们无法更改签名产品。事实上,我们的程序应该使用分离的签名和原始文件。我希望使用“ResourceResolver”,但不幸的是,“XadesVerifier”总是从分离的签名检查文件的uri。以下是用于实例化“ResourceResolver”的源代码(doc.createAttribute(“URI”),“file:/D:/workspace/xades4j-487d7a9bb9e5/data_to_sign/test11.txt”,false);选项。用户资源解算器(解析器)我不懂你的代码。它正在尝试获取现有的冲突解决程序。我建议使用一个自定义解析器,它具有忽略实际URI的逻辑。实际上,您需要实现ResourceResolver API并将其传递给ResourceResolver。您可能可以查看ResolverLocalFilesystem的实现。