How does SOAP Message Encryption work?
- Thilina Buddhika
- Associate Technical Lead - WSO2
WS Security Specification describes enhancements to SOAP messaging to provide message integrity, confidentiality,
non-repudiation etc. It does not introduce new information security concepts, rather it is based on the existing security
concepts like XML encryption, XML signature, etc. It sets the foundation to secure web services by adapting these existing
technologies accordingly.
href="https://www.oasis-open.org/committees/download.php/16790/wss-v1.1-spec-os-SOAPMessageSecurity.pdf" target="_blank" rel="noopener">WS Security Specification
of asymmetric key based encryption. Even if the asymmetric binding is used, it is advised to use symmetric keys for
encryption. In such scenarios, the PKI is used to establish the symmetric keys. Initiator can come up with the symmetric and
encrypt it using the public key of the recipient. Then the recipient can decrypt this key and find out the symmetric key
which is used for encryption.
It is possible to encrypt the whole XML element or just the content of it. WS Security
Specification enforces not to encrypt <S11:Header>, <S12:Header>, <S11:Envelope>, <S12:Envelope>,or
<S11:Body>, <S12:Body> elements. But encrypting the sub elements of those elements are allowed.
If a particular element or content of it is supposed to be encrypted, then that element should be replaced by the
<xenc:EncryptedData> element which is the result of encrypting the original element.
Ex :
<xenc:EncryptedData Id="EncDataId-3" Type="https://www.w3.org/2001/04/xmlenc#Content">...</xenc:EncryptedData>
Symmetric keys used for the encryption operations should be embedded inside
<xenc:EncryptedKey> elements. Each <xenc:EncryptedKey> element should contain a <ds:KeyInfo> element that
contains information about the key used to encrypt the symmetric key. Then there can be a <xenc:ReferenceList> which
is the manifest of the elements which are encrypted. If a <xenc:ReferenceList> element is appearing inside a
<xenc:EncryptedKey> element, it implies that the symmetric key resulted by decrypting the cipher value of the
<xenc:EncryptedKey> element should be used decrypt the elements specified in that refernce list.
<xenc:ReferenceList> is comprised of a list of <xenc:DataReference> elements which contains refernces to the
elements which are encrypted using this key. If we put this in a simplified manner, <xenc:ReferenceList> inside a
<xenc:EncryptedKey> element refers to all the <xenc:EncryptedData> elements which are encrypted using the
symmetric key contained in that <xenc:EncryptedKey> element. Each <xenc:EncryptedData> element should be
referred using <xenc:DataReference> element.
Ex :
<xenc:EncryptedKey Id="EncKeyId-E296581B23458CA12512507910022225"> <xenc:EncryptionMethod Algorithm="https://www.w3.org/2001/04/xmlenc#rsa-1_5"/> <ds:KeyInfo xmlns:ds="https://www.w3.org/2000/09/xmldsig#"> <wsse:SecurityTokenReference> <wsse:KeyIdentifier EncodingType="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="https://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1"> HYL371NzoOs2+IA24VDkBGcUFQM= </wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue> H9l+f1lqTvi4W3vaHwXMhhdfOT8t2t75fzgCkUvjX7ae9FLMEm7/hoQCEurJE4SOmPRXUvLV3MSI21Fcr3HW2OFc1SEpAZQwxma03/iG0jlSyAOOO/j9jitTnmvh tMGI9HShrM0cP77U0GDBTIoXqMSOrzMKbSQ8iz7wl5dG+TY= </xenc:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#EncDataId-3"/> </xenc:ReferenceList> </xenc:EncryptedKey>
Lets come back to the <xenc:EncryptedData> element. Earlier we said that all the
elements which should be encrypted must be replaced by a <xenc:EncryptedData> elements. This element might contain a
<ds:KeyInfo> element which points to another <ds:KeyInfo> element or an attached security token. But it is not
mandatory to have such <ds:KeyInfo> element, if that <xenc:EncryptedData> element is listed in
a <xenc:ReferenceList> of a particuar <xenc:EncryptedKey>. It should contain a </xenc:CipherData>
element, which contains the cipher data.
Ex :
<xenc:EncryptedData Id="EncDataId-3" Type="https://www.w3.org/2001/04/xmlenc#Content"> <xenc:EncryptionMethod Algorithm="https://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <ds:KeyInfo xmlns:ds="https://www.w3.org/2000/09/xmldsig#"> <wsse:SecurityTokenReference xmlns:wsse="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:Reference URI="#EncKeyId-E296581B23458CA12512507910022225"/> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>HTnMneoskQeLew99eIqCLh+8kUAvKozGjsLMfBN8Ji2QDx64Rl53vKqXYybDQeGidWHn9L7OFSEW 6kWuSsDqB+AWQezNgoACcxrNfn7vGwQidD3Kl6aviSaFALzJJkphk29Cip7vSOFmxJn3qIaA82AD rrnPYT57uyPh03XELwrv1Wret3q1uNZ0pnjk6xjYjsQzkAgADUeE/MfWSMdjvpZ6eQ4wwTOmemeh HtVLEdIsKoCyXRBMC9Etiu3KoymArNWRAMgQHvSzBmGxuWCALOHYru8OJpmetZacz5KVqWHifRhP wXFsWOQF3zfBQhJmf4fRiAXkeJ4ZXn3BjT4dz/BVoDaHJFEwK5KY9GRtg0U7Eu3l5k6RNM3ds56N PGP/DhvKJfcFCh4qKVfbWFDVLdeqcRzrHXWuiHTu6BoiwJgzFoQ8vjP6Bw== </xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData>
Having said about the optional <ds:KeyInfo> element inside a
<xenc:EncryptedData> element, now it is possible to take the <xenc:ReferenceList> element out of the
<xenc:EncryptedKey> element if required. In such scenarios, <xenc:EncryptedData> elements should contain the
<ds:KeyInfo> elements pointing to the keys that are used for the encryption. With this option, it is possible to use
multiple keys for encrypting the elements in the same SOAP message.
So lets bring all the bits and pieces together. Following listing depicts a SOAP message with an encrypted soap body.
<soapenv:Envelope xmlns:soapenv="https://schemas.xmlsoap.org/soap/envelope/" xmlns:xenc="https://www.w3.org/2001/04/xmlenc#"> <soapenv:Header xmlns:wsa="https://www.w3.org/2005/08/addressing"> <wsse:Security xmlns:wsse="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"> <xenc:EncryptedKey Id="EncKeyId-E296581B23458CA12512507910022225"> <xenc:EncryptionMethod Algorithm="https://www.w3.org/2001/04/xmlenc#rsa-1_5"/> <ds:KeyInfo xmlns:ds="https://www.w3.org/2000/09/xmldsig#"> <wsse:SecurityTokenReference> <wsse:KeyIdentifier EncodingType="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="https://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1"> HYL371NzoOs2+IA24VDkBGcUFQM= </wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue> H9l+f1lqTvi4W3vaHwXMhhdfOT8t2t75fzgCkUvjX7ae9FLMEm7/hoQCEurJE4SOmPRXUvLV3MSI21Fcr3HW2OFc1SEpAZQwxma03/iG0jlSyAOOO/j9jitTnmvh tMGI9HShrM0cP77U0GDBTIoXqMSOrzMKbSQ8iz7wl5dG+TY= </xenc:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#EncDataId-3"/> </xenc:ReferenceList> </xenc:EncryptedKey> </wsse:Security> <wsa:To>https://localhost:8081/axis2/services/sample03</wsa:To> <wsa:MessageID>urn:uuid:EE5C34B1DCEF6DBA991250791000372</wsa:MessageID> <wsa:Action>urn:echo</wsa:Action> </soapenv:Header> <soapenv:Body xmlns:wsu="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-14900151"> <xenc:EncryptedData Id="EncDataId-3" Type="https://www.w3.org/2001/04/xmlenc#Content"> <xenc:EncryptionMethod Algorithm="https://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <ds:KeyInfo xmlns:ds="https://www.w3.org/2000/09/xmldsig#"> <wsse:SecurityTokenReference xmlns:wsse="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:Reference URI="#EncKeyId-E296581B23458CA12512507910022225"/> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>HTnMneoskQeLew99eIqCLh+8kUAvKozGjsLMfBN8Ji2QDx64Rl53vKqXYybDQeGidWHn9L7OFSEW 6kWuSsDqB+AWQezNgoACcxrNfn7vGwQidD3Kl6aviSaFALzJJkphk29Cip7vSOFmxJn3qIaA82AD rrnPYT57uyPh03XELwrv1Wret3q1uNZ0pnjk6xjYjsQzkAgADUeE/MfWSMdjvpZ6eQ4wwTOmemeh HtVLEdIsKoCyXRBMC9Etiu3KoymArNWRAMgQHvSzBmGxuWCALOHYru8OJpmetZacz5KVqWHifRhP wXFsWOQF3zfBQhJmf4fRiAXkeJ4ZXn3BjT4dz/BVoDaHJFEwK5KY9GRtg0U7Eu3l5k6RNM3ds56N PGP/DhvKJfcFCh4qKVfbWFDVLdeqcRzrHXWuiHTu6BoiwJgzFoQ8vjP6Bw== </xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </soapenv:Body> </soapenv:Envelope>
An asymmetric key is used for encrption. <xenc:EncryptedKey> element contains a
<ds:KeyInfo> element which can be used by the recipient to locate the correct private key from his keystore to decrypt
the symmetric key. <wsse:SecurityTokenReference> element inside that <ds:KeyInfo> element specifies a
ThumbprintSHA1 value that can be used as a key identifier. Then it contains a <xenc:CipherData> which contains the
cipher text of the symmetric key. Decrypting this cipher text using the private key of the recipient with result with the
symmetric key.
Then it has the <xenc:ReferenceList> with a single <xenc:DataReference> element.
That <xenc:DataReference> element refers to an element using the URI fragment #EncDataId-3. If you carefully observe,
you will note that, this URI fragment is the ID of the <xenc:EncryptedData> which is the child element of the soap
body. That <xenc:EncryptedData> element contains a <ds:KeyInfo> element which points to the
<xenc:EncryptedKey> element mentioned above using a SecurityToken Reference. <xenc:CipherValue> contains the
encrypted content of the soap body, which should be decrypted using the symmetric key.
Encryption of SOAP headers is not discussed here, to keep this note short as much as possible.
Refer to
target="_blank" rel="noopener">WS Security Specification
Author
Thilina Buddhika, Software Engineer, WSO2, [email protected]