Digital signature 反签名无效(xades4j)

Digital signature 反签名无效(xades4j),digital-signature,xml-signature,xades4j,Digital Signature,Xml Signature,Xades4j,我必须先签名,然后用签名对一些xml进行反签名。这是我的代码: private String singXadesEnveloped(String mode, Document document, Certificate[] certificateChain, PrivateKey signingKey, String mimeType, String encoding) throws XAdES4jException, ClassCastException, Unsuppo

我必须先签名,然后用签名对一些xml进行反签名。这是我的代码:

private String singXadesEnveloped(String mode, Document document, Certificate[]    certificateChain, PrivateKey signingKey, String mimeType, String encoding)
        throws XAdES4jException, ClassCastException, UnsupportedEncodingException, ClassNotFoundException,
        InstantiationException, IllegalAccessException {

    try {
    DataObjectDesc desc = null; 
    KeyingDataProvider kp = new StaticKeyingDataProvider(certificateChain, signingKey);
    BasicSignatureOptionsProvider bop=new BasicSignatureOptionsProvider() {

        public boolean signSigningCertificate() {
            // TODO Auto-generated method stub
            return false;
        }

        public boolean includeSigningCertificate() {
            // TODO Auto-generated method stub
            return true;
        }

        public boolean includePublicKey() {
            // TODO Auto-generated method stub
            return true;
        }
    };
    //System.out.println("bop.includePublic="+bop.includePublicKey());
    XadesSigningProfile sp = new XadesBesSigningProfile(kp).withTimeStampTokenProvider(CertumFreeTimeStampProvider.class).withBasicSignatureOptionsProvider(bop);
    XadesSigner signer = sp.newSigner(); 

    desc = new DataObjectReference("")
    .withDataObjectFormat(new DataObjectFormatProperty(mimeType, encoding))
    .withTransform(new EnvelopedSignatureTransform());


    SignedDataObjects dataObjects = new SignedDataObjects(desc)
    .withCommitmentType(AllDataObjsCommitmentTypeProperty.proofOfOrigin());

    Element el = document.getDocumentElement();
    //System.out.println("element="+el.getNodeName());
    XadesSignatureResult sign = signer.sign(dataObjects, el);
    String signed_xml = serializeDocument(document);
    //System.out.println("\n\nPodpisany xml:\n"+signed_xml+"\n\n");


    XadesSignatureFormatExtender extender = new XadesFormatExtenderProfile().getFormatExtender();
    Element sigElem = sign.getSignature().getElement();
    //System.out.println("\n\nTag do podpisu:"+sigElem.getNodeName()+"\n\n");
    XMLSignature sig = new XMLSignature(sigElem, sigElem.getOwnerDocument().getBaseURI());
    XadesSigningProfile profile = new XadesBesSigningProfile(kp).withTimeStampTokenProvider(CertumFreeTimeStampProvider.class).withBasicSignatureOptionsProvider(bop);
    final XadesSigner counterSigner = profile.newSigner();


   // .withTransform(new ExclusiveCanonicalXMLWithoutComments());


    //System.out.println("\n\nNode sygnatury: "+sig.getElement().getNodeName()+"\n\n");


         Collection<UnsignedSignatureProperty> usp = new ArrayList(1);
            usp.add(new CounterSignatureProperty(counterSigner));

            extender.enrichSignature(sig, new UnsignedProperties(usp));

    } catch (XMLSignatureException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (XMLSecurityException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    /*-----------------------------------------------------*/

    //alternatywny sposób realizowania podpisu
    //new Enveloped(signer).sign(document.getDocumentElement());
    DOMSource domSource = new DOMSource(document);
    StringWriter writer = new StringWriter();
    StreamResult result = new StreamResult(writer);
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer;
    try {
        transformer = tf.newTransformer();
        transformer.transform(domSource, result);
    } catch (TransformerConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (TransformerException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    //System.out.println("\n\nsignXades signed before serializedocument: \n\n" + writer.toString());
    //return serializeDocument(signed_document);
    return writer.toString();
}
私有字符串SingxadeEnveloped(字符串模式、文档文档、证书[]CertificateCain、私有密钥签名密钥、字符串mimeType、字符串编码)
抛出XADES4JEException、ClassCastException、UnsupportedEncodingException、ClassNotFoundException、,
实例化异常,非法访问异常{
试一试{
DataObjectDesc desc=null;
KeyingDataProvider kp=新的静态KeyingDataProvider(CertificateCain,signingKey);
BasicSignatureOptionsProvider bop=新的BasicSignatureOptionsProvider(){
公共布尔签名证书(){
//TODO自动生成的方法存根
返回false;
}
公共布尔值IncludeDesigningCertificate(){
//TODO自动生成的方法存根
返回true;
}
公共布尔值includePublicKey(){
//TODO自动生成的方法存根
返回true;
}
};
//System.out.println(“bop.includePublic=“+bop.includePublicey());
XADESigningProfile sp=新的XadesBesSigningProfile(kp)。withTimeStampTokenProvider(CertumFreeTimeStampProvider.class)。WithBasicSignatureOptions Provider(bop);
xadesigner signer=sp.newSigner();
desc=新的DataObjectReference(“”)
.withDataObjectFormat(新的DataObjectFormatProperty(mimeType,编码))
.withTransform(新信封SignatureTransform());
SignedDataObjects dataObjects=新的SignedDataObjects(描述)
.withCommitmentType(AllDataObjsCommitmentTypeProperty.prooforigin());
Element el=document.getDocumentElement();
//System.out.println(“element=“+el.getNodeName());
XadesSignatureResult sign=signer.sign(数据对象,el);
字符串签名\u xml=序列化文档(文档);
//System.out.println(“\n\nPodisany xml:\n”+已签名的xml+”\n\n”);
XADESignatureFormatExtender extender=新的XADESFormatExtender配置文件().getFormatExtender();
Element sigElem=sign.getSignature().getElement();
//System.out.println(“\n\n标记为podpisu:+sigElem.getNodeName()+”\n\n”);
XMLSignature sig=newxmlsignature(sigElem,sigElem.getOwnerDocument().getBaseURI());
XADESigningProfile=新的XadesBesSigningProfile(kp)。withTimeStampTokenProvider(CertumFreeTimeStampProvider.class)。WithBasicSignatureOptions Provider(bop);
final XadesSigner counterSigner=profile.newSigner();
//.withTransform(新的排他性Anonicalxml无注释());
//System.out.println(“\n\n节点系统名称:“+sig.getElement().getNodeName()+”\n\n”);
集合usp=新阵列列表(1);
usp.add(新的会签财产(会签人));
扩展器。enrichSignature(sig,新的未签名属性(usp));
}捕获(XMLSignatureException e1){
//TODO自动生成的捕捉块
e1.printStackTrace();
}捕获(XMLSecurityException e1){
//TODO自动生成的捕捉块
e1.printStackTrace();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
/*-----------------------------------------------------*/
//备选方案NY sposób realizowania podpisu
//新信封(签名者)。签名(document.getDocumentElement());
DOMSource DOMSource=新的DOMSource(文档);
StringWriter编写器=新的StringWriter();
StreamResult结果=新的StreamResult(writer);
TransformerFactory tf=TransformerFactory.newInstance();
变压器;
试一试{
变压器=tf.新变压器();
transformer.transform(domSource,result);
}捕获(TransformerConfiguration异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(转换异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
//System.out.println(“\n\nsignXades在序列化文档之前签名:\n\n”+writer.toString());
//返回文件(已签署的文件);
返回writer.toString();
}
它为我的xml签名并添加反签名。 不幸的是,当我验证我的xml时,签名很好,但反签名不好(签名的摘要与文件数据的摘要不相等)

我的代码有什么问题?这是带有签名和反签名的XML:

如果问题是“签名摘要不等于文件数据摘要”,则证书没有帮助。 但是,我用其他软件验证了你的签名。反签名中的摘要和签名值似乎没有问题。您能得到验证应用程序中使用的哈希值吗

在计数器签名中签名的签名值的哈希blob:

<ds:SignatureValue xmlns:adr="http://crd.gov.pl/xml/schematy/adres/2008/05/09/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:inst="http://crd.gov.pl/xml/schematy/instytucja/2008/05/09/" xmlns:iso639-2="http://lcweb.loc.gov/standards/iso639-2/" xmlns:meta="http://crd.gov.pl/xml/schematy/meta/2008/05/09/" xmlns:oso="http://crd.gov.pl/xml/schematy/osoba/2008/05/09/" xmlns:str="http://crd.gov.pl/xml/schematy/struktura/2008/05/09/" xmlns:wnio="http://epuap.gov.pl/FeResourceServlet/wzor_lokalny/twmud37012/Wniosek_odpowiedzi/" Id="xmldsig-2d270d0c-76d2-4638-9e5a-fc149b383552-sigvalue">
orHos56IR77hfwBp2bas3L9E9X4K/oVAyRCkW/00gxon5ZEKCmmT5GhT/Bty6AOC5MsMwDKSgFbe
ysO7kqg5DuSOFPGocR3cBszH4w25Uoouk/0mxKU6BdTKl8Ud/N2RA/rUhvYBvH+JDjOrp+mtEmym
skBfxHssfzecGXQFtzskJLCMaxIhBQIw8RIOkREzFNozCCEw8uo9GEuzyfRC3EypVy8hL1p/qG2z
Ytf2lEJ4EastuCN5etHQSSVT4I9yeJulTj58e4d2IjtcVjJlpV1yetysv0R7E3cJ9YWaL4vH3Yhx
DtVIepegelZa37omW3GMtvIEDa6bdBx8WyMJLA==
</ds:SignatureValue>

或HOS56IR77HFWBP2BAS3L9E9X4K/oVAyRCkW/00gxon5ZEKCmmT5GhT/Bty6AOC5MsMwDKSgFbe
YSO7KQG5DUSOFPGOCR3CBSZH4W25UOOK/0MXKU6BDTCL8UD/N2RA/rUhvYBvH+JDjOrp+mtEmym
skBfxHssfzecGXQFtzskJLCMaxIhBQIw8RIOkREzFNozCCEw8uo9GEuzyfRC3EypVy8hL1p/qG2z
YTF2LEJ4EASTUCN5ETHQSSVT4I9YEJ58E4D2IJTCVJJLPV1YETYSV0R7E3CJ9YWAL4VH3YHX
DtVIepegelZa37omW3GMtvIEDa6bdBx8WyMJLA==

验证应用程序失败的一个可能原因是您没有在反签名中使用规范化算法。我不熟悉xades4J,但我认为它的API不允许向反签名添加规范化算法。

信息分散在评论上,因此我在这里发布最终答案。正在使用的第三方工具(可能是Sigilum符号,您能确认吗?)需要
http://uri.etsi.org/01903#CountersignedSignature
计数器签名中主
参考
类型
上的值。XAdES规范声明,此引用在反签名用例中不是强制性的,这意味着第三方工具应该接受它们。尽管如此,xades4j的最新版本始终包含elemen