Exam 70-554 - Encrypt and decrypt a SOAP message.
Section 1
- Part 3
- Topic 3
Encrypt and decrypt a SOAP message.
- Encrypt a SOAP message.
- Decrypt an encrypted SOAP message.
Summary
WSE 3.0 enables developers to encrypt and decrypt SOAP Messages using both symmetric and asymmetric encryption. For more details on the cryptography option, please refer to the cryptography section of the guide for Exam 70-553. WSE Encrypts the entire body of the SOAP message by default. There are several types of security tokens that can be used to encrypt a SOAP message including: X509 Certificate, Username token, Kerberos Ticket, Security Context token or custom token.
To encrypt a SOAP message you must create a custom policy assertion that secures SOAP Messages. To do this you must create a classes that inherits from the ReceiveSecurityFilter class and classes that inherits from SendSecurityFilter Class. You need one set of classes for the Client and one set for the Server. In the SendSecurityFilter classes you will override the SecureMessage Method and create or get the token that you want to use to encrypt the message. Then create an instance of the EncryptedData class passing the token into the constructor. Then you add the EncryptedData instance to the security Elements collection of the base class. The following is an example of encrypting a message with a Kerberos token from msdn:
public override void SecureMessage(SoapEnvelope envelope, Security security)
{
KerberosToken kerbToken = new KerberosToken("host/" + hostname +
"@" + domainName); // Encrypt the SOAP request by using the Kerberos ticket.
EncryptedData enc = new EncryptedData(kerbToken);
security.Elements.Add(enc);
}
To decrypt the message on the other side you will need to override the ValidateMessageSecurity method. In this method you will need to iterate through the security elements collection and check if each item is an instance of EncryptedData. The following example from msdn checks that the message was signed using a username token.
public override void ValidateMessageSecurity(SoapEnvelope envelope, Security security)
{
bool IsEncrypted = false;
foreach (ISecurityElement element in security.Elements)
{
if (element is EncryptedData)
{
// The given context contains an EncryptedData element.
EncryptedData encrypt = element as EncryptedData; // The SOAP message is encrypted.
if (encrypt.SecurityToken is UsernameToken)
// The SOAP body is encrypted by a UsernameToken.
IsEncrypted = true ;
}
} if (!IsEncrypted)
throw new SecurityFault("Message did not meet security requirements.");
}
Note that decrypting messages differs a little based on the type of token you are using. X509 tokens and Kerberos tickets can be decrypted through configuration. Basically how it works is you define your policy in a policy file that has all the details for Kerberos or X509 and then use a Policy Attribute on the web service itself. Here is an example of a Kerberos policy file from msdn:
<policies>
<extensions>
<extension name="kerberosSecurity"
type="Microsoft.Web.Services3.Design.KerberosAssertion, Microsoft.Web.Services3, Version=3.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<extension name="kerberos"
type="Microsoft.Web.Services3.Design.KerberosTokenProvider, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<extension name="requireActionHeader"
type="Microsoft.Web.Services3.Design.RequireActionHeaderAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</extensions>
<policy name="ServicePolicy">
<kerberosSecurity establishSecurityContext="false" signatureConfirmation="false" protectionOrder="SignBeforeEncrypting" deriveKeys="true">
<token>
<kerberos targetPrincipal="host/contoso4@contoso.com" impersonationLevel="Identification" />
</token>
<protection>
<request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />
<response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />
<fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
</protection>
</kerberosSecurity>
<requireActionHeader />
</policy>
</policies>
And here is an example of the Policy attribute being applied to the Web Service class from msdn:
[WebService(Namespace = "http://www.contoso.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Policy("ServicePolicy")]
public class Service : System.Web.Services.WebService
{
Other Resources & Links:
Encrypting a SOAP Message
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wse3.0/html/56078682-ce45-4ceb-88f9-a4049b1222d4.asp
How To: Encrypting a SOAP Message
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wse3.0/html/56078682-ce45-4ceb-88f9-a4049b1222d4.asp
Discrete Security Operations Supported By the Built-in Security Tokens (Has details on encryption/decryption by security token)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wse3.0/html/5b4d4c91-c12c-4ec1-9cf8-a09d068ba0cc.asp