2012-02-13 109 views
4

大家好,您好!驗證SOAP消息的簽名

這是我的請求消息:

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

我嘗試驗證這是關係到身體標記的<ds:DigestValue>RJhc1ZVjXdUQEIwLTH356p7H0QY=</ds:DigestValue>。有像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/" /> 

???我必須執行哪些操作(規範化/轉換/加密)?

任何幫助表示感謝。提前致謝。

+1

我會使用像支持WS-Security的metro,axis2這樣的框架。其他一切都可能成爲一場噩夢(您必須閱讀WS-S規範:-) – home 2012-02-13 07:47:57

+0

您是否第一次閱讀[Exclusive XML Canonicalization](http://www.w3.org/TR/xml-exc-c14n/)規範? – 2012-02-13 07:49:18

+0

嗯,還沒有,但謝謝你的答案!我會做的。你知道任何文章,包含我的問題的建議嗎? – Dmitry 2012-02-13 07:53:17

回答

4

解決的辦法是:

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你需要驗證簽名的公鑰。

+0

謝謝德米特爲您提供完整的解決方案。我得到'javax.xml.crypto.MarshalException:當我用'/ Envelope/Header/Security/Signature'和'/ Envelope/Body'調用這個方法時,文檔實現必須支持DOM Level 2並且是名字空間感知的。你知道它從哪裏來嗎? – Bludwarf 2014-09-30 14:29:30

+0

爲什麼我會得到:java.lang.IllegalArgumentException:Id不是屬性 \t at javax.xml.crypto.dom.DOMCryptoContext.setIdAttributeNS – lonelyloner 2017-12-28 05:50:16

1

嗯,我已經設法驗證參考摘要: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是< SignedInfo>標記。我讀過this。我仍然不知道如何以這種方式格式化xml。實際上,它有許多工作要做內存莫名其妙