Encrypting one parameter on a WebMethod with WSE

One of the attendees here at TechEd asked me how to encrypt only one of the parameters on a WebMethod with WSE.  I figured others might be curious too so here is some code that does this.

Web Service code:

[WebMethod]
public string HelloWorld(string UnsecureParam, SecureString SecureParam)
{
    return "Secured string: "
        + SecureParam.SecureData
        + " UnsecureParam: "
        + UnsecureParam;
}
public class SecureString
{
// Set the Oasis Id that our security reference will
// point to
    [XmlAttribute("Id", Namespace="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")]
    public string ID;
    [XmlText]
    public string SecureData;
}

My client code looks like this:

localhost.Service1Wse proxy = new localhost.Service1Wse();
X509CertificateStore store =
    X509CertificateStore.CurrentUserStore(
X509CertificateStore.OtherPeople);
store.OpenRead();
X509CertificateCollection certs =
store.FindCertificateBySubjectName(
"CN=WSE2QuickStartServer");
X509SecurityToken tok = new X509SecurityToken(certs[0]);
proxy.RequestSoapContext.Security.Tokens.Add(tok);
// The “#SecureParam“ matches the Id attribute value
// on our secure parameter. This tells WSE to encrypt
// that particular piece
EncryptedData enc = new EncryptedData(tok, "#SecureParam");
proxy.RequestSoapContext.Security.Elements.Add(enc);
localhost.SecureString secStr = new localhost.SecureString();
// Set the attribute to match the Ref in the
// encrypteddata object. Don't include the '#'.
secStr.Id = "SecureParam";
secStr.Value = "This should be encrypted.";
string ret = proxy.HelloWorld("This is not encrypted.",
secStr);

And as proof that this works...here's the message that I pulled from the WSE trace.  Note that the second param is encrypted!  (Both params are bold below).  Sorry about the formatting but I couldn't handle trying to pretty format it after cleaning up all the code above.

<soap:Envelope xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:wsa="https://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsse="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

<soap:Header>
<wsa:Action>https://tempuri.org/HelloWorld</wsa:Action>
<wsa:MessageID>uuid:8e53bb0d-a2eb-4c7b-9918-ff9d0a1599d9</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>https://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>https://localhost/partiallyencrypted/service1.asmx</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="Timestamp-f90df3d5-10db-447a-961a-a7638fc010c9">
<wsu:Created>2004-05-28T21:16:02Z</wsu:Created>
<wsu:Expires>2004-05-28T21:21:02Z</wsu:Expires>
</wsu:Timestamp>
<wsse:BinarySecurityToken ValueType="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" xmlns:wsu="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-d00793c5-ec61-418a-99ad-e345a0332bff">MIIBxDCCAW6gAwIBAgIQYpjr4FOk3IFNSd3lJj6ItzANBgkqhkiG9w0BAQQFADAWMRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ4MTBaFw0zOTEyMzEyMzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0U2VydmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLkqglArInukRlDwXbcjN3zxfsjeaLd+IvfyD5o35pUjpTkPwPXmApScr8UVQxB5JDRSVlMz1lUQ6CBLFLGIAQOpbPKn2oul3VmKAf9nRQf9PLU+biWozZXkhebIya43D75r5+5NUq1RbQiCC4qIobRqUdg6adujBY333wJy4YgwIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcNAQEEBQADQQAGSGNKz1gZqbXN8JYl0PQM7ngkHfW1mQ88NRYADmoHw5A/rUZDHAPs5HLSn3i5iXlRwT91v3SU6iuaAid+Mwyq</wsse:BinarySecurityToken>
<xenc:EncryptedKey xmlns:xenc="https://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="https://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="https://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:Reference URI="#SecurityToken-d00793c5-ec61-418a-99ad-e345a0332bff" ValueType="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>v0IfLD9rxujkOR0aPeJrTHxsSH8zvpXAJhyjVdzHm5+3DBhH4esJhutwzS5Yi48ots5F4qkBly4ioa+9MRIr7oK3lNdAICs1l8QLxLc0Z/4OocHn0YaU0sb3fXULqtvxrgz+UrDanweZVhtTxb1HIuiJ62BuQaaROZsUckm062I=</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#EncryptedContent-3d793117-f020-4236-a0a0-0ed545d9bf1a" />
</xenc:ReferenceList>
</xenc:EncryptedKey>
</wsse:Security>
</soap:Header>
<soap:Body>
<HelloWorld xmlns="https://tempuri.org/">
<UnsecureParam>This is not encrypted.</UnsecureParam>
<SecureParam d4p1:Id="SecureParam" xmlns:d4p1="https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<xenc:EncryptedData Id="EncryptedContent-3d793117-f020-4236-a0a0-0ed545d9bf1a" Type="https://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="https://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="https://www.w3.org/2001/04/xmlenc#aes128-cbc" />
<xenc:CipherData>
<xenc:CipherValue>FRFCiqtv8xiIHsDDShdQ8jsdBsTUTd0jNQNcLFsfqbzgYU6pBu/WVY9E9+0W5oS4</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</SecureParam>
</HelloWorld>
</soap:Body>
</soap:Envelope>