Java 验证SOAP消息的签名
大家好 这是我的请求消息:Java 验证SOAP消息的签名,java,web-services,ws-security,Java,Web Services,Ws Security,大家好 这是我的请求消息: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.o
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<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="1">
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="X509-A3BCFAE87E12A8813813289737654441">MIICCTCCAXKgAwIBAgIETzVFkDANBgkqhkiG9w0BAQUFADBJMQswCQYDVQQGEwJSVTEKMAgGA1UECBMBMTEKMAgGA1UEBxMBMTEKMAgGA1UEChMBMTEKMAgGA1UECxMBMTEKMAgGA1UEAxMBMTAeFw0xMjAyMTAxNjI4MDBaFw0xMjA1MTAxNjI4MDBaMEkxCzAJBgNVBAYTAlJVMQowCAYDVQQIEwExMQowCAYDVQQHEwExMQowCAYDVQQKEwExMQowCAYDVQQLEwExMQowCAYDVQQDEwExMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdwxyRNYlWADnTtzH9/s/ehhD2iFzvF2xI+tBNyhbBb98EQNiIFdEegwGPhtd3Cfe1lQqtddWdFX2uLqozMAgd1KzSEuH9lI5DPiir3RfVdy+Irs5ZYiD/H4/DcUMUNyVcWspf9oG25wNdwNHKY8Aqz2269uYMCCoIBuWt6POwFQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAGLgTXbn7h2rBjv++6OopDooRifc4e2k+9sSTpLNegs9OvQzR8DpmQ/6Vt0RFprIdXSv+IVMcmL8Q2dmI9v0R61NIhdEjzSVbO2+PF9h1ShUARzMawRC/EOdjwVjDsk1WMxF18+wvH9SQxBSK3H2WpJbDWBxZCOW5CK1N6AKKJiC</wsse:BinarySecurityToken>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-2">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soap" />
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#id-1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>RJhc1ZVjXdUQEIwLTH356p7H0QY=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>F0q0NV7kaSbAcsLHxVpYD1bQ1RAJcw6wPapDKAM9PIcs7EuS9S5PlE4cQMfAp1WgsKa91r3op1OQ5UrYmmdj/UneYawdPIYSaoFBGjndTXZnOCKp4YfRTQGZ2EVJRFHJbPsTsqHedPAyJLHhciViguTGeuA0hZAQN97KB/9ZLmY=</ds:SignatureValue>
<ds:KeyInfo Id="KI-A3BCFAE87E12A8813813289737654452">
<wsse:SecurityTokenReference wsu:Id="STR-A3BCFAE87E12A8813813289737654483">
<wsse:Reference URI="#X509-A3BCFAE87E12A8813813289737654441" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soap:Header>
<soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-1">
<stubMethod xmlns="http://ws_base.ws.stuff/" />
</soap:Body>
</soap:Envelope>
或者只是
<stubMethod xmlns="http://ws_base.ws.stuff/" />
???我必须执行哪些操作(规范化/转换/加密)
任何帮助都将不胜感激。提前感谢。我已经成功验证了参考摘要:规范化->sha1->base64。 问题是我无法验证签名本身。我试过:
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(signedInfoTag);
trans.transform(source, result);
String xmlString = sw.toString();
Signature sig = Signature.getInstance("SHA1withRSA", "BC");
sig.initVerify(cert.getPublicKey());
sig.update(xmlString.getBytes());
byte[] signatureValueDecoded = Translator.base64StringToByteArray(signatureValue);
sig.verify (signatureValueDecoded);
其中xmlString是一个 private boolean validateSignature(Node signatureNode, Node bodyTag, PublicKey publicKey) {
boolean signatureIsValid = false;
try {
// Create a DOM XMLSignatureFactory that will be used to unmarshal the
// document containing the XMLSignature
String providerName = System.getProperty
("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
(Provider) Class.forName(providerName).newInstance());
// Create a DOMValidateContext and specify a KeyValue KeySelector
// and document context
DOMValidateContext valContext = new DOMValidateContext(new X509KeySelector(publicKey), signatureNode);
valContext.setIdAttributeNS((Element) bodyTag, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id");
// Unmarshal the XMLSignature.
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
// Validate the XMLSignature.
signatureIsValid = signature.validate(valContext);
} catch (Exception ex) {
logger.error("An Error Raised while Signature Validation");
logger.error("Cause: " + ex.getCause());
logger.error("Message: " + ex.getMessage());
}
return signatureIsValid;
}
在哪里
并向X509KeySelector提供验证签名所需的公钥。我在尝试在Soap头中的wss:Security标记中构建签名时遇到了类似的问题。 我正试图建立一个参考。如果使用空字符串作为第一个参数添加:
Reference reference = factory.newReference("", digestMethod, transforms, null, null);
它无法工作,因为我从服务器收到以下消息:
- “转换引用元素()后未找到数据。一个或多个 可能缺少转换。“
Reference reference = factory.newReference("#Body", digestMethod, transforms, null, null);
我得到以下错误:
- javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolvexception: 无法解析ID为Body的元素
- Id不是当前的属性 javax.xml.crypto.dom.DOMCryptoContext.setIdAttributeNS.
我现在有点困了。如果有什么发现,我会回来。我会使用metro、axis2等支持WS-Security的框架。其他一切都可能成为一场噩梦(您必须阅读WS-S规范:-)您是否首先阅读了规范?嗯,还没有,但谢谢您的回答!我会的。你知道有哪篇文章对我的问题提出了建议吗?你是如何生成标题的?谢谢Dmitry提供完整的解决方案。我得到了
javax.xml.crypto.marshallException:当我使用/Envelope/Header/Security/Signature
和/Envelope/Body
调用此方法时,文档实现必须支持DOM级别2和命名空间感知。你知道它来自哪里吗?为什么我会得到:java.lang.IllegalArgumentException:Id不是javax.xml.crypto.dom.DOMCryptoContext的属性。setIdAttributeNS@Bludwarf您的DocumentBuilderFactory
实现不知道名称空间。在解析文档之前,必须调用documentBuilderFactory.setNamespaceAware(true)
。
Reference reference = factory.newReference("", digestMethod, transforms, null, null);
Reference reference = factory.newReference("#Body", digestMethod, transforms, null, null);
signContext.setIdAttributeNS(soapBody,
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id");