Aug 21, 2009

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

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 :

    
    
        
            
                HYL371NzoOs2+IA24VDkBGcUFQM=
            
        
    
    
        
            H9l+f1lqTvi4W3vaHwXMhhdfOT8t2t75fzgCkUvjX7ae9FLMEm7/hoQCEurJE4SOmPRXUvLV3MSI21Fcr3HW2OFc1SEpAZQwxma03/iG0jlSyAOOO/j9jitTnmvhtMGI9HShrM0cP77U0GDBTIoXqMSOrzMKbSQ8iz7wl5dG+TY=
        
    
    
        
    

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 :

    
    
        
            
        
    
    
        HTnMneoskQeLew99eIqCLh+8kUAvKozGjsLMfBN8Ji2QDx64Rl53vKqXYybDQeGidWHn9L7OFSEW
            6kWuSsDqB+AWQezNgoACcxrNfn7vGwQidD3Kl6aviSaFALzJJkphk29Cip7vSOFmxJn3qIaA82AD
            rrnPYT57uyPh03XELwrv1Wret3q1uNZ0pnjk6xjYjsQzkAgADUeE/MfWSMdjvpZ6eQ4wwTOmemeh
            HtVLEdIsKoCyXRBMC9Etiu3KoymArNWRAMgQHvSzBmGxuWCALOHYru8OJpmetZacz5KVqWHifRhP
            wXFsWOQF3zfBQhJmf4fRiAXkeJ4ZXn3BjT4dz/BVoDaHJFEwK5KY9GRtg0U7Eu3l5k6RNM3ds56N
            PGP/DhvKJfcFCh4qKVfbWFDVLdeqcRzrHXWuiHTu6BoiwJgzFoQ8vjP6Bw==
        
    

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.

    
        
            
                
                
                    
                        
                            HYL371NzoOs2+IA24VDkBGcUFQM=
                        
                    
                
                
                    
                        H9l+f1lqTvi4W3vaHwXMhhdfOT8t2t75fzgCkUvjX7ae9FLMEm7/hoQCEurJE4SOmPRXUvLV3MSI21Fcr3HW2OFc1SEpAZQwxma03/iG0jlSyAOOO/j9jitTnmvhtMGI9HShrM0cP77U0GDBTIoXqMSOrzMKbSQ8iz7wl5dG+TY=
                    
                
                
                    
                
            
        
        http://localhost:8081/axis2/services/sample03
        urn:uuid:EE5C34B1DCEF6DBA991250791000372
        urn:echo
    
    
        
            
            
                
                    
                
            
            
                HTnMneoskQeLew99eIqCLh+8kUAvKozGjsLMfBN8Ji2QDx64Rl53vKqXYybDQeGidWHn9L7OFSEW
                    6kWuSsDqB+AWQezNgoACcxrNfn7vGwQidD3Kl6aviSaFALzJJkphk29Cip7vSOFmxJn3qIaA82AD
                    rrnPYT57uyPh03XELwrv1Wret3q1uNZ0pnjk6xjYjsQzkAgADUeE/MfWSMdjvpZ6eQ4wwTOmemeh
                    HtVLEdIsKoCyXRBMC9Etiu3KoymArNWRAMgQHvSzBmGxuWCALOHYru8OJpmetZacz5KVqWHifRhP
                    wXFsWOQF3zfBQhJmf4fRiAXkeJ4ZXn3BjT4dz/BVoDaHJFEwK5KY9GRtg0U7Eu3l5k6RNM3ds56N
                    PGP/DhvKJfcFCh4qKVfbWFDVLdeqcRzrHXWuiHTu6BoiwJgzFoQ8vjP6Bw==
                
            
        
    

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.

2 comments:

Swapna Soni said...

Hi,
I have a question in rampart. Could you please answer it.
In a client class we have our custom module and rampart engaged. While sending the request, we are setting some header tags in outflow handler of custom module. while request going out, first custom module's outflow handler is executing then rampart module's outflow handler is executing. When request goes til webservice, (webservice is also having rampart and custom module engage), then webservice custom module's inflow handler is executing. We have a code to extract custom header tags in inflow handler. But the custom header tags we have set in outflow handler is not coming till inflow handler. And in inflow handler the envelope is in encrypt form. Could you please tell me how to get these header values in inflow handler.

thilinamb said...

Hi Swapna,

IMO at the service end, Rampart should be the first handler. This is how we are doing it in Axis2. Then Rampart will carry out all the necessary cryptographic and policy validations and hand over the security processed message to the next handler. So in server side, placing the Rampart handler before the custom handler will resolve your issue.

/ thilina

Post a Comment