使用OpenSAML为SOAP Body生成分离式签名的问题求助
使用OpenSAML为SOAP Body生成分离式签名的问题求助
需求描述
我需要为SOAP Body生成分离式签名(detached signing),目标XML格式如下:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <env:Header xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="true"> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-B9561BC9E482A7482717165370736895"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/> <ds:Reference URI="#id-B9561BC9E482A7482717165370736684"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> </ds:Transform> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/> <ds:DigestValue>some value</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>some value </ds:SignatureValue> </ds:Signature> </wsse:Security> </env:Header> <soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-B9561BC9E482A7482717165370736684"> <Test/> </soap:Body> </soap:Envelope>
当前实现代码
我基于OpenSAML做了部分实现,先配置签名的基础参数:
signature.setSigningCredential(credential); signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
接着添加指向SOAP Body的内容引用:
Element bodyElement = (Element) doc.getDocumentElement().getElementsByTagName("SOAP-Body").item(0); String bodyId = "body123"; // Unique reference ID bodyElement.setAttribute("Id", bodyId); bodyElement.setIdAttribute("Id", true); DocumentInternalIDContentReference uriContentReference = new DocumentInternalIDContentReference( bodyId); uriContentReference.setDigestAlgorithm(SignatureConstants.ALGO_ID_DIGEST_SHA256); uriContentReference.getTransforms().add(SignatureConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS); signature.getContentReferences().add(uriContentReference);
最后执行签名操作:
Signer.signObject(signature);
遇到的错误
执行过程中抛出了如下异常:
Exception in thread "main" org.opensaml.xmlsec.signature.support.SignatureException: Signature computation error at org.opensaml.xmlsec.signature.support.impl.provider.ApacheSantuarioSignerProviderImpl.signObject(ApacheSantuarioSignerProviderImpl.java:62) at org.opensaml.xmlsec.signature.support.Signer.signObject(Signer.java:73) at com.amazon.bancomatpayremittancelambda.service.OpenSAMLDetachedSignature.main(OpenSAMLDetachedSignature.java:98) Caused by: org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID body123 Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID body123 Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID body123 Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID body123 at org.apache.xml.security.signature.Reference.calculateDigest(Reference.java:744) at org.apache.xml.security.signature.Reference.generateDigestValue(Reference.java:405) at org.apache.xml.security.signature.Manifest.generateDigestValues(Manifest.java:205) at org.apache.xml.security.signature.XMLSignature.sign(XMLSignature.java:631) at org.opensaml.xmlsec.signature.support.impl.provider.ApacheSantuarioSignerProviderImpl.signObject(ApacheSantuarioSignerProviderImpl.java:59) ... 2 more
问题总结
tl;dr
我该如何用OpenSAML生成符合上述示例的XML请求?
备注:内容来源于stack exchange,提问作者SynAck




