While most of my Web service examples involve a single request and a response, a Web service interaction might easily include a series of messages, as in a negotiation or other iterative process. In such Web service conversations, each message must include the sender s security token and a signature created using the related proof-of-possession. While WS-Security enables parties to exchange credentials, it is more secure to not have to supply a base set of credentials, such as a username, X.509 certificate, or some other proprietary authentication credential, in every message. Security tokens contain valuable data, and passing them in every message only increases the likelihood that they might be intercepted, which allows an attacker to determine who the clients of your Web service are.
Also it can be expensive, in terms of processor resources, to use PKI encryption, an asymmetric encryption mechanism, to secure each message in a conversation. This is because of the nature of the asymmetric cryptographic algorithms used to encrypt data using a public key and decrypt it using a private key. Compared to symmetric encryption, public key encryption algorithms must handle much larger numbers , and therefore they require much more processing. To alleviate this performance hit, most public key schemes only use the public key to encrypt a symmetric session key, which is, in turn , used to encrypt the actual message data. The receiver then decrypts this symmetric session key using their private key and uses the symmetric session key to decrypt the message data. In many cases this symmetric key is used as a session key and cached for the rest of the conversation, and once the symmetric key has been established, PKI is no longer used in the conversation. This is actually how WSE implements message encryption using X.509 certificates.
In this previous scenario, the symmetric session key can be auto-generated, used in only one message, and thrown away after the message was decrypted. While normally discarded, when the symmetric session key is transported securely, it can be kept secure and be used to sign and encrypt a response back to the initial party. Using a disposable, symmetric multi-session secret key is the basis for secure Web service conversations, as described in the WS-SecureConversation specification. This specification defines a security context as a special type of authentication where a security token can be shared among the communicating parties for the lifetime of a communications association and can be used to exchange multiple messages. This specification also defines a new type of security token called the security context token that includes a security context identifier and the related secret session key. The shared secret key in a security context token is longer lived than a single-session key, but since it lasts only as long as the conversation, is much shorter lived than base credentials. Also, since this key is generated randomly by a security token service and the security context is identified only by an identifier, the security context token itself contains no information related to any participants in the conversation.
A security context can be initiated by a participant in a Web service conversation so that the interaction will benefit from the added layer of security defined in WS-SecureConversation that I have just described. A security context can be obtained in one of the following ways:
Distributed by a separate security token service as in security token service.
Generated by a participant in the conversation and trusted by the other participant.
Generated by a participant in the conversation based on a negotiation between participants in the conversation.
A participant in a conversation that creates security contexts must implement WS-SecureConversation. In addition, a security context service must implement both WS-SecureConversation and WS-Trust.
Regardless of how a security context was created, that context must be distributed securely to all participants in the conversation. This distribution is accomplished using the functionalities for handling security tokens defined in WS-Security, for which the WS-SecureConversation specification defines a new type of security token, called the security context token. Only after all participants have received their copies of the security context token can the secure conversation begin. Also, in order to securely distribute this token, which initially contains a secret cryptographic key, the participants must be able to send and receive encrypted messages to each other, which means that there must already be either shared symmetric keys, public and private X.509 certificates, or some other custom authentication mechanism that supports encryption.
A security context token is a special type of security token used for establishing security context for a secure Web service conversation. This token contains an identifier used to reference an established security context, and it may also include expiration information as well as the secret key or reference to the key used to secure the conversation. The following is an example of a SecurityContextToken element that contains an encrypted secret key, which can be decrypted using the recipient s secret key:
In this example, the SecurityContextToken element contains the shared secret key, which, of course, is encrypted using the referenced security token. After the initial message that distributes this key, all subsequent messages in the conversation include this token in the Security message header (without the encrypted shared secret key, of course) and use the shared secret key to sign the message and also to encrypt it if needed. Any message that is received where the signature does not match the security context token referenced in the Identifier element should be rejected. The Created and Expired elements are used when the lifetime of the security context is limited. Any messages that fall outside of this lifetime should also be rejected.
As I mentioned, any participant in a Web service conversation can generate a security context for all to use, as long as they follow the requirements set forth in WS-SecureConversation. When sending an unsolicited security context token, the initiator sends a RequestTokenRequestResponse message to the other parties. This message references the SecurityContextToken included in the message header. The WSE 2.0 API can be used to generate such a message, as well as the security context.
Another method for creating a security context is to request a security context token from an STS. When requesting a security context token from such a service, the request must include security tokens sufficient to authenticate the requestor at the service issuing the security context token. The following message requests a security context token from an STS:
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
After authenticating the request, the service will return a SecurityContextToken , as follows :
<wsu:Created wsu:Id="Id-0b7e1eb0-0384-4b95-ab30-070e5949f789"> _
<wsu:Expires wsu:Id="Id-9edcffb2-548f-402d-a2ac-809ed0228dd5"> _
Once obtained, this security context is communicated securely with other participants using a RequestSecurityTokenResponse message, where the secret key for the SecurityContextToken is encrypted in such a way that it can be decrypted by the recipient.
For even more security, rather than relying on a secret key with a fixed value for the security context, WS-SecureConversation recommends using the secret key to derive a new shared secret for each message iteration in the conversation. Using derived keys that change with each message reduces the changes of replay attacks. When using derived keys, the base key is initially distributed in the security context token, and all subsequent messages in the security context are secured using a derived key token, which is derived from this initial security context token and that reference this cached token. Derived key-based authentication information is included in the Security message header using the DerivedKeyToken element. The following is an example of a DerivedKeyToken element:
In this example, we assume that both parties have already negotiated the basis for deriving keys from the base secret and that this message is the second derivation from this base key, hence the Generation value of 2. DerivedKeyToken also supports the following child elements used when negotiating the basis for deriving keys:
Offset and Length Specifies the length of derived keys when variable key lengths are being used.
Label Specifies a name for this derived key sequence, which itself is used in the derivation.
Nonce Specifies the nonce value, which is used as a cryptographic seed for the derivation.
Properties Encapsulates the previous key-derivation properties.
When deriving keys for a secure conversation, the P_SHA-1 algorithm is used over a concatenation of the base secret key, the label values from both parties, and the nonce. WSE 2.0 does implement a DerivedKeyToken object that can be used to include derived keys in SOAP messages, but I will not show examples of derived keys in this book. For more information on derived keys, see the WS-SecureConversation specification.