【问题标题】:Validating a Signature of a SOAP Message验证 SOAP 消息的签名
【发布时间】:2012-02-13 07:41:13
【问题描述】:

大家好!

这是我的请求消息:

<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>

我尝试验证与 body 标签相关的&lt;ds:DigestValue&gt;RJhc1ZVjXdUQEIwLTH356p7H0QY=&lt;/ds:DigestValue&gt;。像ds:CanonicalizationMethodds:Transforms 这样的标签让我很困惑。我的问题是如何验证身体部位?首先,我应该使用什么标签来开始验证

<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>

或者只是

<stubMethod xmlns="http://ws_base.ws.stuff/" /> 

???我必须执行哪些操作(规范化/转换/加密)???

感谢您的帮助。提前致谢。

【问题讨论】:

  • 我会使用像 Metro、axis2 这样支持 WS-Security 的框架。其他一切都可能成为噩梦(您必须阅读 WS-S 规范 :-)
  • 您是否先阅读了Exclusive XML Canonicalization 规范?
  • 嗯,还没有,但谢谢你的回答!我会做的。你知道任何文章,其中包含对我的问题的建议吗?
  • 你是如何生成该标题的?

标签: java web-services ws-security


【解决方案1】:

解决办法是:

 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;
}

在哪里

public class X509KeySelector extends KeySelector {

PublicKey key;

/**
 * Constructor.
 *
 * @param key a public key of a certificate which need to be validated.
 */
public X509KeySelector(PublicKey key) {
    this.key = key;
}

/**
 * @return a KeySelectorResult with a predefined key.
 */
public KeySelectorResult select(KeyInfo keyInfo,
                                KeySelector.Purpose purpose,
                                AlgorithmMethod method,
                                XMLCryptoContext context) throws KeySelectorException {
    return new KeySelectorResult() {
        @Override
        public Key getKey() {
            return key;
        }
    };
}

}

并给 X509KeySelector 一个您需要验证签名的公钥。

【讨论】:

  • 感谢 Dmitry 提供完整的解决方案。当我用/Envelope/Header/Security/Signature/Envelope/Body 调用此方法时,我得到javax.xml.crypto.MarshalException: Document implementation must support DOM Level 2 and be namespace aware。你知道它是从哪里来的吗?
  • 为什么我得到:java.lang.IllegalArgumentException:Id 不是 javax.xml.crypto.dom.DOMCryptoContext.setIdAttributeNS 的属性
  • @Bludwarf 你的DocumentBuilderFactory 实现不支持命名空间。在解析文档之前,您必须调用 documentBuilderFactory.setNamespaceAware(true)
【解决方案2】:

好吧,我已经成功验证了参考摘要:canonicalize -> 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 是一个 标记。我读过this。我仍然不知道,如何以这种方式格式化 xml。实际上它必须以某种方式在内存中完成

【讨论】:

    【解决方案3】:

    我在尝试在 Soap 标头中的 wss:Security 标记内构建签名时遇到了类似的问题。 我正在尝试建立一个参考。如果我用空字符串作为第一个参数添加它:

    Reference reference = factory.newReference("", digestMethod, transforms, null, null);
    

    它不起作用,因为我从服务器收到以下消息:

    • "转换参考元素()后找不到数据。一个或多个 可能缺少转换。"

    如果我使用如下 ID 添加它:

    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.ResourceResolverException: 无法解析 ID Body 的元素

    此处已将其描述为错误:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8017265

    因此,我一直在尝试使用 setIdAttributeNS 方法来设置 ID,而不是使用 body.setAttribute(Id, "Body"); 直接在 body 上设置它

    signContext.setIdAttributeNS(soapBody, 
    "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id");
    

    但我遇到了与@Dustin Sun 相同的问题。我也收到 java.lang.IllegalArgumentException:

    • Id 不是属性 javax.xml.crypto.dom.DOMCryptoContext.setIdAttributeNS.

    我现在有点卡住了。如果有什么我会回来的。

    【讨论】:

      猜你喜欢
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      • 2016-07-29
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多