计数器签名无效(xades4j)

时间:2014-09-02 08:52:46

标签: digital-signature xml-signature xades4j

我必须签名,然后签名一些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();
}

它签署我的xml并添加计数器签名。 不幸的是,当我验证我的xml时,签名非常好,但是签名没有(签名的摘要与文件数据中的摘要不相同)。

我的代码出了什么问题?这是带签名和计数器签名的XML:

Signed and countersigned xml file

2 个答案:

答案 0 :(得分:0)

如果问题是&#34;签名的摘要与文件数据的摘要不相同&#34;,证书没有帮助。 但是,我使用其他软件验证了您的签名。计数器签名中的摘要和签名值似乎没问题。你能获得验证应用程序中使用的散列值吗?

在计数器签名中签名的签名值的散列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>

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

答案 1 :(得分:0)

信息分散在评论中,所以我在这里发布最终答案。正在使用的第三方工具(可能是Sigilum Sign,您能否确认?)需要计数器签名中主http://uri.etsi.org/01903#CountersignedSignature的{​​{1}}上的Type值。 XAdES规范指出,对于此签名用例,此引用不是必需的,这意味着第三方工具应该接受它们。尽管如此,最新版本的xades4j始终包含元素。

如果您在maven上获得最新版本的xades4j,则应该修复此问题。如果您在xades4j网站的下载部分获得二进制文件,请再次获取它们,因为该程序包有一个小的不连贯性。