How does the SOAP Message Encryption work?

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 signatures, etc. It sets the foundation to secure web services by adapting these existing technologies accordingly.

This post is intended to provide a simplified explanation on how XML encryption works with SOAP messages as per the WS Security Specification.

WS Security Specification recommends to use symmetric keys for encryption. This is mainly due to the low performance factor 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="http://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="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
                <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                    <wsse:SecurityTokenReference>
                        <wsse:KeyIdentifier
                                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/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">
                            HYL371NzoOs2+IA24VDkBGcUFQM=
                        </wsse:KeyIdentifier>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
                <xenc:CipherData>
                    <xenc:CipherValue>
                        H9l+f1lqTvi4W3vaHwXMhhdfOT8t2t75fzgCkUvjX7ae9FLMEm7/hoQCEurJE4SOmPRXUvLV3MSI21Fcr3HW2OFc1SEpAZQwxma03/iG0jlSyAOOO/j9jitTnmvhtMGI9HShrM0cP77U0GDBTIoXqMSOrzMKbSQ8iz7wl5dG+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="http://www.w3.org/2001/04/xmlenc#Content">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <wsse:SecurityTokenReference
                        xmlns:wsse="http://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="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
    <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <wsse:Security xmlns:wsse="http://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="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
                <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                    <wsse:SecurityTokenReference>
                        <wsse:KeyIdentifier
                                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/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">
                            HYL371NzoOs2+IA24VDkBGcUFQM=
                        </wsse:KeyIdentifier>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
                <xenc:CipherData>
                    <xenc:CipherValue>
                        H9l+f1lqTvi4W3vaHwXMhhdfOT8t2t75fzgCkUvjX7ae9FLMEm7/hoQCEurJE4SOmPRXUvLV3MSI21Fcr3HW2OFc1SEpAZQwxma03/iG0jlSyAOOO/j9jitTnmvhtMGI9HShrM0cP77U0GDBTIoXqMSOrzMKbSQ8iz7wl5dG+TY=
                    </xenc:CipherValue>
                </xenc:CipherData>
                <xenc:ReferenceList>
                    <xenc:DataReference URI="#EncDataId-3"/>
                </xenc:ReferenceList>
            </xenc:EncryptedKey>
        </wsse:Security>
        <wsa:To>http://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="http://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="http://www.w3.org/2001/04/xmlenc#Content">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <wsse:SecurityTokenReference
                        xmlns:wsse="http://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.

I did not discussed about encrypting SOAP headers, to keep this note short as much as possible.

Refer to WS Security Specification for a comprehensive description about the SOAP message encryption.

<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/&#8221;
xmlns:xenc=”http://www.w3.org/2001/04/xmlenc#”&gt;
<soapenv:Header xmlns:wsa=”http://www.w3.org/2005/08/addressing”&gt;
<wsse:Security xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&#8221;
soapenv:mustUnderstand=”1″>
<xenc:EncryptedKey Id=”EncKeyId-E296581B23458CA12512507910022225″>
<xenc:EncryptionMethod Algorithm=”http://www.w3.org/2001/04/xmlenc#rsa-1_5″/&gt;
<ds:KeyInfo xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”&gt;
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier
EncodingType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary&#8221;
ValueType=”http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1″&gt;
HYL371NzoOs2+IA24VDkBGcUFQM=
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>
H9l+f1lqTvi4W3vaHwXMhhdfOT8t2t75fzgCkUvjX7ae9FLMEm7/hoQCEurJE4SOmPRXUvLV3MSI21Fcr3HW2OFc1SEpAZQwxma03/iG0jlSyAOOO/j9jitTnmvhtMGI9HShrM0cP77U0GDBTIoXqMSOrzMKbSQ8iz7wl5dG+TY=
</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI=”#EncDataId-3″/>
</xenc:ReferenceList>
</xenc:EncryptedKey>
</wsse:Security>
<wsa:To>http://localhost:8081/axis2/services/sample03</wsa:To&gt;
<wsa:MessageID>urn:uuid:EE5C34B1DCEF6DBA991250791000372</wsa:MessageID>
<wsa:Action>urn:echo</wsa:Action>
</soapenv:Header>
<soapenv:Body xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd&#8221;
wsu:Id=”Id-14900151″>
<xenc:EncryptedData Id=”EncDataId-3″ Type=”http://www.w3.org/2001/04/xmlenc#Content”&gt;
<xenc:EncryptionMethod Algorithm=”http://www.w3.org/2001/04/xmlenc#tripledes-cbc”/&gt;
<ds:KeyInfo xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”&gt;
<wsse:SecurityTokenReference
xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”&gt;
<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>

About this entry