我需要为带有附件的 SOAP 请求添加数字签名。我尝试了几种使用 xmlsec-3.0.2.jar 和 javax.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,添加数字签名,但是没有
下面是我的代码。
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();}
请提出解决方案。