Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Digging into SecureConversation - Part II

4.50/5 (3 votes)
17 Nov 2006CPOL6 min read 1  
Take a deep look into the Security protocol of Enhanced Web Services, part II: analyzing the Response message.

Introduction

In the first part of this article, we have analyzed the request message of an RST/RSTR exchange between Cardspace and my own implementation of a Secure Token Service (STS) also known as Identity Provider. In this second part, we are going to dig into the response message sent back by the STS in response to the request message that we analyzed previously.

As for the first part, we only focus on the Secure Conversation protocol that protects the RST/RSTR data. This protocol is used to transport many type of exchanges in the new Web Services specifications. I will eventually write another article about the RST/RSTR that is used to transport the SAML token from the STS to the requestor.

Background

This article doesn't use any coding, however it assumes a good knowledge of XML and some understanding of basic cryptography like using symmetric and asymmetric algorithms for encryption and signature purposes. I just attached a small tool that helps understand the basics of cryptography used in this article.

If you haven't read the Part 1 of this article, I encourage you to do so because we are going to use concepts that were detailed in the first part.

Part 2: Response SOAP message containing the RSTR (RequestSecurityTokenResponse)

Structure of the SOAP message

You can refer to the same chapter of Part 1 to get the description of the structure of a SOAP message. As for the request message, a lot of useful information to analyze the whole message is contained in the Security element of the header. We are going to see first how to decrypt the encrypted content of the Security element.

Decrypting the encrypted elements of the header

As for the request message, we must get the list of encrypted data in the whole message. This is given by the ReferenceList element in Security. This element is shown below.

XML
<e:ReferenceList xmlns:e="http://www.w3.org/2001/04/xmlenc#">
  <e:DataReference URI="#_3" />
  <e:DataReference URI="#_6" />
</e:ReferenceList>

In this message, we have two encrypted elements. Let's first focus on the element with Id="_6", which is the one in the Security element. As we have seen in the first part, the EncryptedData contains a KeyInfo that will help to find the key used to encrypt the data. The whole EncryptedData element is described listing 1.

Listing 1

XML
<e:EncryptedData 
        Type="http://www.w3.org/2001/04/xmlenc#Element" Id="_6" 
        xmlns:e="http://www.w3.org/2001/04/xmlenc#">
    <e:EncryptionMethod 
        Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
  <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
    <o:SecurityTokenReference>
            <o:Reference URI="#_4" />
    </o:SecurityTokenReference>
    </KeyInfo>
    <CipherData xmlns="http://www.w3.org/2001/04/xmlenc#">
    <CipherValue>L9uCbEDhVjcB4gTBqC3GtyaiGGY8P7...
               oDJ7pB21bAA48xoLzk2ks</CipherValue>
    </CipherData>
</e:EncryptedData>

If we look at the EncryptionMethod element, we get to know that the data has been encrypted using a symmetric AES algorithm with a key of 128 bits. So the fist thing we have to do is find the key that was used for the encryption in order to decrypt the data. This information is given by the KeyInfo element. This element references an element that has the Id="_4". Looking up in the Security element, we can find that it points to the following DerivedKeyToken element:

XML
<sc:DerivedKeyToken u:Id="_4" 
    xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-
             200401-wss-wssecurity-utility-1.0.xsd" 
    xmlns:sc="http://schemas.xmlsoap.org/ws/2005/02/sc">
  <o:SecurityTokenReference>
    <o:KeyIdentifier 
       ValueType="http://docs.oasis-open.org/wss/oasis-
                  wss-soap-message-security-1.1#EncryptedKeySHA1">
      UbPUL5eLKdw25Xptln4DOGN3YLI=
    </o:KeyIdentifier>
  </o:SecurityTokenReference>
  <sc:Offset>0</sc:Offset>
  <sc:Length>16</sc:Length>
  <sc:Nonce>i2uYqtgSQCE/KE7C4E86UQ==</sc:Nonce>
</sc:DerivedKeyToken>

This type of an element has been seen previously in the Part 1 of this article. A DerivedKeyToken element contains information to compute a derived key. The algorithm used to compute this key is a PSHA1 that takes a master key, a nonce, and a label. The label value is fixed by Microsoft to the string value "WS-SecureConversationWS-SecureConversation". The SecurityTokenReference is used to get the Master Key value. In the request message, the master key was referenced as an EncryptedKey. This master key is in fact shared by both messages. The response message is to be handled by the requestor which was the one that created the request message, and by the way knows the master key as it generated it.

The purpose of the SecurityTokenReference is to give a way to the requestor to check that the key that was used by the STS is the one that was generated by the requestor itself.

The SecurityTokenReference contains a KeyIdentifier with the attribute ValueType indicating that the reference to the key we are looking for is an EncryptedKeySHA1. It means that the base64 value UbPUL5eLKdw25Xptln4DOGN3YLI= represents the SHA1 of the encrypted key value that was sent in the request message. If you refer to Part 1, this value was XsApZde4j3w35HGt…YVHkbY0MFZIg=. The requestor must have kept this encrypted data and mapped it to the master key value. As when using RSA encryption, a cipher is always different for the same data, the requestor cannot encrypt the master key another time to get the encrypted value. Of course, to do the computation, you must first get the binary values of the Base 64 data.

To check this, you can use the tool I provided with the first part of this article.

With the master key, it is now possible to compute the derived key and use it to decrypt the data from the encrypted element. After applying the decryption, you should get the data of listing 2. These data are ASCII values that are in fact a Signature element for the message.

Listing 2

XML
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
  <SignedInfo>
    <CanonicalizationMethod 
       Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
    <SignatureMethod 
       Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1" />
    <Reference URI="#_0">
      <Transforms>
        <Transform 
           Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      </Transforms>
      <DigestMethod 
         Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      <DigestValue>cf8q2Vw2rW5blihu0xWaxCdU4QA=</DigestValue>
    </Reference>
    <Reference URI="#_1">
      <Transforms>
        <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      </Transforms>
      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      <DigestValue>LDb2+mKJ9h0YUEQ2IILUtKjSWGg=</DigestValue>
    </Reference>
    <Reference URI="#uuid-8346502e-ebb7-b631-0704-403dd21ca6ec-1">
      <Transforms>
        <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      </Transforms>
      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      <DigestValue>fJ9Jk5L5Du0pY6FSIQnuBRKtVmI=</DigestValue>
    </Reference>
    <Reference URI="#_5">
      <Transforms>
        <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      </Transforms>
      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      <DigestValue>SjeSg51ZvqDFfu46wsHK2+QmZEo=</DigestValue>
        </Reference>
    </SignedInfo>
  <SignatureValue>7ddH6wlhQNJPw6VRMORxP6eD37Q=</SignatureValue>
  <KeyInfo>
    <o:SecurityTokenReference 
         xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-
                  200401-wss-wssecurity-secext-1.0.xsd">
      <o:Reference URI="#_4" />
    </o:SecurityTokenReference>
  </KeyInfo>
</Signature>

Decrypting the Body encrypted data

Now that we have decrypted the Signature element, decrypting the body will be a peace of cake! The EncryptedData element of the Body is given below:

XML
<e:EncryptedData 
      Type="http://www.w3.org/2001/04/xmlenc#Content" 
      Id="_3" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
  <e:EncryptionMethod 
     Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
  <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
    <o:SecurityTokenReference 
         xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-
                  200401-wss-wssecurity-secext-1.0.xsd">
      <o:Reference URI="#_4" />
    </o:SecurityTokenReference>
  </KeyInfo>
  <CipherData xmlns="http://www.w3.org/2001/04/xmlenc#">
    <CipherValue>83suvxZAJ+4hOeo/baEFfdu20yKkU4unm1QJ4N9
                  WrUVOa...BVNOKR5yumvi/aQ==</CipherValue>
  </CipherData>
</e:EncryptedData>

If we take a look at the KeyInfo, we can see that it references the same key, which means that we just need to use the derived key that we computed to decrypt the Signature. Running the AES128 decryption algorithm on the data will give us some ASCII data that is the XML element RequestSecurityTokenResponse. This element has been constructed by the STS in response to the RST that was decrypted in the Body of the request message.

The next step that has to be done, is to verify the integrity of the message that the requestor receives. Previously, we decrypted a Signature element. This element contains information that shall be used to verify this.

Verifying the Signature

If you refer to the Signature element we had in the request message and that has been analyzed in the Part 1 of this article, you can see that the structure of this one is totally similar. As there is no further interest to detail again the verification process of the Signature, you would find it in the Part 1 of this article.

Points of Interest

We have seen in those two parts quite a lot of concepts and information. WCF totally hides the WS-* protocols, and makes the use of security features as simple as a line of XML in a configuration file. However, you can see that a lots of things happen under the hood. It is particularly important to understand what really goes on when you activate the security feature, when you have to deal with interoperability like I have to do.

So I hope that with this article, you will have been interested to learn a bit about the security protocols that are used in WCF. Of course, this is just the study of a particular case of interoperability, but I think that it can help you understand better how to use security in WCF as it helped me make my mind clearer about those features by writing this article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)