java中如何给带有附件的SOAP请求添加数字签名

问题描述 投票:0回答:0

我需要为带有附件的 SOAP 请求添加数字签名。我尝试了几种使用 xmlsec-3.0.2.jarjavax.xml.crypto 库的方法。但它们都没有按预期工作。

<ds:Signature Id="XXXXXXX"
                xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:SignedInfo>
                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
                    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                    <ds:Reference URI="">
                        <ds:Transforms>
                            <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                            <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
                                <ds:XPath>not(ancestor-or-self::eb:TraceHeaderList or ancestor-or-self::eb:Via)</ds:XPath>
                            </ds:Transform>
                            <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>ssssssssssssss</ds:DigestValue>
                    </ds:Reference>
                    <ds:Reference URI="cid:attachmentID">
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>yyyyyyyyyyyyyyyyyyyyy</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>dfdgrtr</ds:SignatureValue>
                <ds:KeyInfo>
                    <ds:KeyValue>
                        <ds:RSAKeyValue>
                            <ds:Modulus>ghrtjjyty</ds:Modulus>
                            <ds:Exponent>Aaaa</ds:Exponent>
                        </ds:RSAKeyValue>
                    </ds:KeyValue>
                    <ds:X509Data>
                        <ds:X509SubjectName>cn=dgrgree,o=hhnn,l=Melbourne,st=Victoria,c=AU</ds:X509SubjectName>
                        <ds:X509Certificate>fdghfhtyrrrrt</ds:X509Certificate>
                    </ds:X509Data>
                </ds:KeyInfo>
            </ds:Signature>
        </SOAP-ENV:Header>

使用xmlsec-3.0.2.jar,添加数字签名,但是没有标签,Reference标签中URI属性的值为“附件文件路径”,而不是“cid:attachmentID”。

下面是我的代码。

public void addSignature(Resource keyStoreFile, String keyStorePassword, String keyStoreAlias, SOAPMessage soapMessage) throws Exception {

//create basic structure of signature
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
File attachedFile = new File("file path to attachment");
Element element = null;
Document doc = dBuilder.parse(new InputSource(new StringReader(printSOAPResponse(soapMessage))));
Init.init();
org.apache.xml.security.signature.XMLSignature sig =
    new org.apache.xml.security.signature.XMLSignature(doc, null, SignatureMethod.RSA_SHA1);
element = doc.getDocumentElement();
element.normalize();
element.getElementsByTagName("SOAP-ENV:Header").item(0).appendChild(sig.getElement());
Transforms transforms = new Transforms(doc);
transforms.addTransform(CanonicalizationMethod.ENVELOPED);
String xpathExpr = "not(ancestor-or-self::eb:TraceHeaderList or ancestor-or-self::eb:Via)";
XPathContainer xpathContainer = new XPathContainer(doc);
xpathContainer.setXPath(xpathExpr);
// Add the XPath transform to the Transforms object
transforms.addTransform(Transforms.TRANSFORM_XPATH, xpathContainer.getElement());
transforms.addTransform(CanonicalizationMethod.INCLUSIVE);
ResolverLocalFilesystem fileResolver = new ResolverLocalFilesystem();
ResourceResolver.register(fileResolver, false);
//Sign the content of SOAP Envelope
sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);
//Adding the attachment to be signed
sig.addDocument(attachedFile.toURI().toURL().toString(), null, Constants.ALGO_ID_DIGEST_SHA1);
// Load the KeyStore and get the signing key and certificate.
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(keyStoreFile.getInputStream(), keyStorePassword.toCharArray());
KeyStore.PrivateKeyEntry keyEntry =
    (KeyStore.PrivateKeyEntry) keyStore.getEntry(keyStoreAlias, new KeyStore.PasswordProtection(keyStorePassword.toCharArray()));
X509Certificate x509Certificate = (X509Certificate) keyEntry.getCertificate();
sig.setId("WmEbXML-Signature-54cl6h00gi08isbf003ient2");
sig.addKeyInfo(x509Certificate.getPublicKey());
sig.addKeyInfo(x509Certificate);
sig.sign(keyEntry.getPrivateKey());
DOMImplementationLS domImplementationLS = (DOMImplementationLS) doc.getImplementation();
LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
LSOutput lsOutput = domImplementationLS.createLSOutput();
lsOutput.setEncoding("UTF-8");
Writer stringWriter = new StringWriter();
lsOutput.setCharacterStream(stringWriter);
lsSerializer.write(doc, lsOutput);
String content = stringWriter.toString();}

请提出解决方案。

java soap digital-signature attachment xml-signature
© www.soinside.com 2019 - 2024. All rights reserved.