计数器签名无效(xades4j)

问题描述:

我必须签名,然后签名一些xml签名。这是我的代码:计数器签名无效(xades4j)

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

+0

该代码似乎是正确的。您能否提供验证签名所需的证书以及包含的TS令牌,以便我可以尝试重现问题? – lgoncalves 2014-09-02 21:21:21

+0

我在外部程序中验证我签名的XML,所以我真的不知道我应该发给你什么(羞耻我......)。如果它可以帮助,这是链接到您可以下载程序的页面(它也会在系统中安装一些证书)。 [第一或页面上第二个链接] [1] [1]:http://sigillum.pl/pliki_do_pobrania.html 我能得到怎样 “TS包括令牌” 送他们到你? – Tomi 2014-09-03 05:46:28

+0

我只需要证书颁发机构证书来验证签名。也许他们是公开的? – lgoncalves 2014-09-03 15:12:04

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

如果你在maven上得到最新版本的xades4j,这应该是固定的。如果你在xades4j网站的下载部分获得了二进制文件,请重新安装它们,因为这个软件包有一点不协调。

+0

这是很好的信息,因为我使用1.3.0创建计数器签名。我现在尝试1.3.1 :-)实际上,经过10分钟的工作(将1.3.1上传到存储库并重新构建小程序),它...起作用(签名和签名验证)!非常感谢Igoncalves! :-) – Tomi 2014-09-15 05:44:54

如果问题是“签名的摘要是不是从文件数据摘要平等”,证书不帮忙。 但是,我使用其他软件验证了您的签名。柜台签名中的摘要和签名值似乎没问题。你能得到验证应用程序中使用的散列值吗?

在柜台签名签署的签名值的散列斑点:

<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不允许向计数器签名添加规范化算法。

+0

这是在我用来验证我的会签文件的应用程序中签名的xml文件。当然,它验证... [文件] [1] [1]:https://www.dropbox.com/s/uwjiiuy6ai7z489/02_09_test_sig_kontr%20%282%29.xades?dl=0 – Tomi 2014-09-03 12:23:50

+0

我使用的软件将此第二个签名视为无效,我相信这是正确的。由主签名签名的引用(URI =“”)的散列无效。您的两个签名都是ENVELOPED(表示包含ds:Signature的完整XML文件已签名)。第二个签名包含与第一个签名相同的哈希值;但是签名的blob不一样(在第一个文件中你有一个由签名覆盖的“ Moez 2014-09-03 14:05:14

+0

计数器签名具有指定的规范化algortihms,即使它们不是,XML- DSIG定义了默认设置 – lgoncalves 2014-09-03 15:17:43