SOAP message signature verification

Hi everybody!

This is my request message:

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

I am trying to check <ds:DigestValue>RJhc1ZVjXdUQEIwLTH356p7H0QY=</ds:DigestValue> which is associated with the body tag. There are tags like ds:CanonicalizationMethod and ds:Transforms that really confuse me. My question is how to check a part of the body? First, what tag should I get to start checking

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

or simply

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

??? What operations (canonization / conversion / encryption) should I perform?

Any help is appreciated. Thanks in advance.

+4
source share
2 answers

Decision:

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

Where

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

and to provide the X509KeySelector public key, you need to verify the signature.

+4
source

Well, I managed to check the reference digest: canonicalize -> sha1 -> base64. The problem is that I cannot verify the authenticity of the signature itself. I tried:

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

where xmlString is <SignedInfo>. I read this one . However, I do not know how to format XML in this way. In fact, this should be done in memory somehow

+2
source

Source: https://habr.com/ru/post/1396140/


All Articles