Sunday, April 17, 2016

C# SOAP v1.0 project with WS-Encryption & WS-Signing

Leave a Comment

I have been tasked with a job to create an app that connects to a web service that uses Soap V1.0 with WS-Security.

I have been able to connect successfully using Soap UI. The Soap Service is sent via HTTPS, the SOAP message must be signed with a x509 cert and the soap body must be encrypted with their SSL.

The Working SOAP XML looks like this:

    <soapenv:Envelope xmlns:ns="http://www.qwerty.com/esi/common/1.0" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">         <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">             <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">                 <wsu:Timestamp wsu:Id="TS-1D010A91DEF5E45ACE145991958150741">                     <wsu:Created>2016-04-06T05:13:01.507Z</wsu:Created>                     <wsu:Expires>2016-04-06T05:46:21.507Z</wsu:Expires>                 </wsu:Timestamp>                 <xenc:EncryptedKey Id="EK-1D010A91DEF5E45ACE145991958150539" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">                     <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>                     <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">                         <wsse:SecurityTokenReference>                             <ds:X509Data>                                 <ds:X509IssuerSerial>                                     <ds:X509IssuerName>CN=abc CA asd,O=qwerty ,L=Sydney,C=AU</ds:X509IssuerName>                                     <ds:X509SerialNumber>2334442322</ds:X509SerialNumber>                                 </ds:X509IssuerSerial>                             </ds:X509Data>                         </wsse:SecurityTokenReference>                     </ds:KeyInfo>                     <xenc:CipherData>                         <xenc:CipherValue>SAulApKrrr5M+Fhy5VWKkAug..cut for readability</xenc:CipherValue>                     </xenc:CipherData>                     <xenc:ReferenceList>                         <xenc:DataReference URI="#ED-1D010A91DEF5E45ACE145991958150540"/>                     </xenc:ReferenceList>                 </xenc:EncryptedKey>                 <ds:Signature Id="SIG-1D010A91DEF5E45ACE145991958145938" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">                     <ds:SignedInfo>                         <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">                             <ec:InclusiveNamespaces PrefixList="wsa ns soapenv" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>                         </ds:CanonicalizationMethod>                         <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>                         <ds:Reference URI="#id-1D010A91DEF5E45ACE145991958145837">                             <ds:Transforms>                                 <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">                                     <ec:InclusiveNamespaces PrefixList="ns" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>                                 </ds:Transform>                             </ds:Transforms>                             <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>                             <ds:DigestValue>TRGWcb2SG5CRTP1FC4U1tvqg=</ds:DigestValue>                         </ds:Reference>                     </ds:SignedInfo>                     <ds:SignatureValue>Nnl7..cut for readability</ds:SignatureValue>                     <ds:KeyInfo Id="KI-1D010A91DEF5E45ACE145991958145835">                         <wsse:SecurityTokenReference wsu:Id="STR-1D010A91DEF5E45ACE145991958145836">                             <ds:X509Data>                                 <ds:X509IssuerSerial>                                     <ds:X509IssuerName>CN=query =qwerty ,L=Sydney,C=AU</ds:X509IssuerName>                                     <ds:X509SerialNumber>105asdsa571845470</ds:X509SerialNumber>                                 </ds:X509IssuerSerial>                             </ds:X509Data>                         </wsse:SecurityTokenReference>                     </ds:KeyInfo>                 </ds:Signature>                 <wsse:UsernameToken wsu:Id="UsernameToken-1D010A91DEF5E45ACE145991958145533">                     <wsse:Username>myusername</wsse:Username>                     <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">mypassword</wsse:Password>                     <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">nonce==</wsse:Nonce>                     <wsu:Created>2016-04-06T05:13:01.454Z</wsu:Created>                 </wsse:UsernameToken>             </wsse:Security>             <wsa:Action>http://www.qwerty.com/esi/common/1.0/getAuthenticationExpiryRequest</wsa:Action>             <wsa:MessageID>urn:dill:Software Version:1</wsa:MessageID>             <wsa:To>http://www.qwerty.com/esi/common/v1</wsa:To>         </soapenv:Header>         <soapenv:Body wsu:Id="id-1D010A91DEF5E45ACE145991958145837" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">             <xenc:EncryptedData Id="ED-1D010A91DEF5E45ACE145991958150540" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">                 <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>                 <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">                     <wsse:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">                         <wsse:Reference URI="#EK-1D010A91DEF5E45ACE145991958150539"/>                     </wsse:SecurityTokenReference>                 </ds:KeyInfo>                 <xenc:CipherData>                     <xenc:CipherValue>HEf6zyUibGuAjgUY/cut for readability</xenc:CipherValue>                 </xenc:CipherData>             </xenc:EncryptedData>         </soapenv:Body>     </soapenv:Envelope> 

My Very flawed response sent via C#

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">     <s:Header>         <a:Action s:mustUnderstand="1" u:Id="_1">http://www.qwerty.com/esi/common/1.0/getAuthenticationExpiryRequest</a:Action>         <a:MessageID u:Id="_2">urn:uuid:8531ad33-56fd-4575-ba3b-cc237617f5f8</a:MessageID>         <a:ReplyTo u:Id="_3">             <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>         </a:ReplyTo>         <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo5YvIPcIlqZNsE+PcW7SWU3jm5ZcyzThspFKp7rCG5JTJikACQAA</VsDebuggerCausalityData>         <a:To s:mustUnderstand="1" u:Id="_4">http://it02:8080/esi2/esi-gateway/common/v1</a:To>         <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">             <u:Timestamp u:Id="uuid-f39da944-9f7f-4c48-ad90-69442f958db5-1">                 <u:Created>2016-04-06T05:08:02.239Z</u:Created>                 <u:Expires>2016-04-06T05:13:02.239Z</u:Expires>             </u:Timestamp>             <o:UsernameToken u:Id="uuid-1892a0d2-1f61-4c02-b91b-b969e8ee1d44-1">                 <o:Username>My Username</o:Username>                 <o:Password>MyPassword=</o:Password>             </o:UsernameToken>             <o:BinarySecurityToken u:Id="uuid-1892a0d2-1f61-4c02-b91b-b969e8ee1d44-2" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">MIII3Q==</o:BinarySecurityToken>             <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#rsa-sha1"/>                     <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>qBpW9R+T2WBBySN4iBskNiWs7lk=</DigestValue>                     </Reference>                     <Reference URI="#_2">                         <Transforms>                             <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>                         </Transforms>                         <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>                         <DigestValue>gyelv9es6SoTBFgujy2Qilngr1Y=</DigestValue>                     </Reference>                     <Reference URI="#_3">                         <Transforms>                             <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>                         </Transforms>                         <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>                         <DigestValue>o3ibE52LCPwycD7dwAsKtJa+WMw=</DigestValue>                     </Reference>                     <Reference URI="#_4">                         <Transforms>                             <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>                         </Transforms>                         <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>                         <DigestValue>s2MW+MnmlKI4VtLdAY6vEZbxoco=</DigestValue>                     </Reference>                     <Reference URI="#uuid-f39da944-9f7f-4c48-ad90-69442f958db5-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>7UO6LSMnFDePv9O88EiFigXEAiM=</DigestValue>                     </Reference>                     <Reference URI="#uuid-1892a0d2-1f61-4c02-b91b-b969e8ee1d44-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>ri+XlD6yZMrBP2N4mSO0t/8g9Po=</DigestValue>                     </Reference>                     <Reference URI="#uuid-1892a0d2-1f61-4c02-b91b-b969e8ee1d44-2">                         <Transforms>                             <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>                         </Transforms>                         <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>                         <DigestValue>WZH8tnKlq/XPoUn5KkoqZzdKrdE=</DigestValue>                     </Reference>                 </SignedInfo>                 <SignatureValue>S8U........</SignatureValue>                 <KeyInfo>                     <o:SecurityTokenReference>                         <o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier">FM69HI68yR5C/F5e/WRIHII7BAM=</o:KeyIdentifier>                     </o:SecurityTokenReference>                 </KeyInfo>             </Signature>         </o:Security>     </s:Header>     <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">         <AuthenticationExpiryRequest xmlns="http://www.qwerty.com/esi/common/1.0"/>     </s:Body> </s:Envelope> 

My C# Code thus far:

class Program     {          private static System.ServiceModel.Channels.Binding GetCustomBinding()         {             System.ServiceModel.Channels.AsymmetricSecurityBindingElement asbe = new AsymmetricSecurityBindingElement();             asbe.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12;              asbe.InitiatorTokenParameters = new System.ServiceModel.Security.Tokens.X509SecurityTokenParameters { InclusionMode = SecurityTokenInclusionMode.Never };             asbe.RecipientTokenParameters = new System.ServiceModel.Security.Tokens.X509SecurityTokenParameters { InclusionMode = SecurityTokenInclusionMode.Never };             asbe.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;              asbe.SecurityHeaderLayout = SecurityHeaderLayout.Strict;             asbe.EnableUnsecuredResponse = true;             asbe.IncludeTimestamp = true;             asbe.SetKeyDerivation(false);             asbe.DefaultAlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Basic128;              asbe.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());             asbe.EndpointSupportingTokenParameters.Signed.Add(new X509SecurityTokenParameters());              CustomBinding myBinding = new CustomBinding();             myBinding.Elements.Add(asbe);             myBinding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10, Encoding.UTF8));                         HttpTransportBindingElement httpsBindingElement = new HttpTransportBindingElement();           //  httpsBindingElement.RequireClientCertificate = true ;               myBinding.Elements.Add(httpsBindingElement);              return myBinding;         }          private static void SetClientCredentialsSecurity(ClientCredentials clientCredentials)         {              var store = new X509Store(StoreName.TrustedPeople, StoreLocation.CurrentUser);             store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);              X509Certificate2 certificate = new X509Certificate2();             X509Certificate2 esiCertificate = new X509Certificate2();              foreach (var cert in store.Certificates)             {                 if (cert.FriendlyName.Contains("certname"))                 {                     certificate = cert;                  }                 if (cert.SubjectName.Name.Contains("certname"))                 {                     esiCertificate = cert;                 }               }                clientCredentials.UserName.UserName = "asd";             clientCredentials.UserName.Password = "asd";              string directoryName = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);             clientCredentials.ServiceCertificate.DefaultCertificate = esiCertificate;             clientCredentials.ClientCertificate.Certificate = certificate;          }          private static ServiceReference1.Common10Client GetCredentialingClient()         {             ServiceReference1.Common10Client client = new ServiceReference1.Common10Client(GetCustomBinding(), new EndpointAddress(new Uri("http://asd/esi2/esi-gateway/common/v1"), new DnsEndpointIdentity("esiServer"), new AddressHeaderCollection()));             client.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.None;             SetClientCredentialsSecurity(client.ClientCredentials);              return client;         }           static void Main(string[] args)         {                  using (ServiceReference1.Common10Client client = GetCredentialingClient())                 {                     client.Open();                      ServiceReference1.getAuthenticationExpiryRequest request = new ServiceReference1.getAuthenticationExpiryRequest();                     request.AuthenticationExpiryRequest = new ServiceReference1.AuthenticationExpiryRequest();                      client.getAuthenticationExpiry(request.AuthenticationExpiryRequest);                 }           } 

as you can see they are very different. What I need is: WS-Security - Encryption, Username, Timestamp, Signature.

But I'm unsure how to replicate it in C#

1 Answers

Answers 1

Just reading over what you've asked, I'd say to have a read through Generating XML Documents from XML Schemas and point your schema at the xsd referenced in the original. If that proves too cumbersome, take apart the xsd and instead of manipulating this as xml, manipulate it using a string-builder and shove that down the pipe.

Are you getting errors because of the format not matching up? Or are you getting errors due to the encryption? Can you post them?

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment