I'm attempting to make a client that uses WCF to communicate with a SOAP endpoint made in Java. The service requires me to send my PKCS10 request inside a encrypted SOAP request, using a X509 certificate that I have received from the service using another function, but I can't figure out how to configure WCF properly to allow me to only encrypt but not sign, seeing as I have yet to receive my final certificate from the service.
I've tried to set the X509 certificate I've received from the server as both DefaultCertificate for the service and the ClientCertificate, but no matter what kind of options I set for the binding and endpoint, I always end up with the error "The private key is not present in the X.509 certificate" and that's because (I assume) there are only the following ProtectionLevels in WCF:
None
Sign
EncryptAndSign
I understand the error here because obviously I haven't received the service's private key and setting the service's certificate as the ClientCertificate I would expect this error, but is it me who has misunderstood something here?
Shouldn't it be possible for me to just encrypt the SOAP envelope using the service's public key that I've already received, without having to sign it as well with my own private key (which I haven't actually received yet)?
Related
I have never worked with soap services before, so I might have done something wrong. I have generated a service client reference for the service through it's wsdl with "Svcutil".
I have followed this guide https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-a-wcf-client-to-interoperate-with-wse3-0-services and set up the custom binding.
After that I a client from the reference and supply a new binding that is using WseSecurityAssertion.MutualCertificate10 and the service endpoint address.
I then add a certificate and add theese credentails to the service client:
clientProxy.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(string.Concat(xxx, yyy), GetCertificatePassword(xxx), PersistKeySet);
clientProxy.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2(xxx, "", PersistKeySet);
clientProxy.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = ChainTrust;
clientProxy.ClientCredentials.ServiceCertificate.Authentication.RevocationMode = NoCheck;
This is code that have worked before (but before using wcf and "Svcutil") and I have mostly copied it, but refactored it a bit.
When I call the Web Service I get this error:
System.ServiceModel.FaultException: 'CWWSS5511E: An exception occurred during the decryption of a message. The exception is CWWSS7310E: XML encryption information exists in the security header, however an inbound XML encryption configuration is not present.'
I understand that I encrypt something that I shouldn't and when I compare the request I sent with the old code to the request I send now I can see that this is added in the securityheader:
<e:EncryptedKey Id="_0" xmlns:e="http://www.w3.org/2001/04/xmlenc#"><e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns="http://www.w3.org/2000/09/xmldsig#"/></e:EncryptionMethod><KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
And some info about the key.
I'm wondering what it is I do wrong that the code didn't do before. I can't find any config files so I don't think it's some configuration I have missed. Where might this encryption be set? Is it inside the binding or is it where I set clientCredentials?
So after alot of reading and comparing I finaly figured out that I did not set
ProtectionLevel to System.Net.Security.ProtectionLevel.Sign in the new generation of the service reference file. this was probably hardcoded there in the old ones instead of using a config file to set the ProtectionLevel.
This is what caused the service on the service side to not understand how to decrypt it correctly.
I have an Windows Application consuming OData v4 WebAPI using DataServiceContext. WebApi is over SSL but still I think anyone can trap request using Web Debugging Tools like fiddler (on the Windows Application Host Machine) and can re-issue the request by altering Request Body.
So I was just thinking what if I could encrypt RequestBody of outgoing Request in Windows Application using Public/Private Key in Production Environment. If yes how could I?
Do I need to create custom DataServiceClientRequestMessage or need to hook encryption process somewhere in DataServiceContext.
The Request would be decrypted using MessageHandler.
ServiceStack Encrypted Messaging
Yes, I think you can write your custom DataServiceClientRequestMessage, and overwrite GetStream() to encrypt the output stream.
Then, set the new message to DataServiceContext with DataServiceContext.Configurations.RequestPipeline.OnMessageCreating = new CustomRequestMessage().
You can refer a custom DataServiceClientRequestMessage example at OData github repository. TestDataServiceClientRequestMessage.cs and DataServiceContextWithCustomTransportLayer.cs
I have implemented a SOAP client based on the code in this thread Client to send SOAP request and received response however I would now like to extend this to allow us to encrypt the soap message using X509 certs and tripleDes and wondered if there was a starting point. the output payload i am looking for will need to include an xml segment based on schema http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd and probably also include headers, anybody have any links to behind the scenes with soap encryption.
I have found this Creating Signed SOAP Message as a String with C# aqrticle which seems to be having a similiar issue, where is the theory behind creating the hash values for soap signing.
Bit late to my own funeral but it appears the solution is here:
Creating Signed SOAP Message as a String with C#
I am working on a WCF client to consume a third party web service over which I have no control. It works with a custom binding and WS Security. No app.config, all through code. I can successfully send requests and receive responses. However, it seems .Net cannot decrypt the service responses, so I have to do it manually. I have implemented a custom encoder and overriden the ReadMessage method. I have access to the raw SOAP response. I have seen code in MSDN as well as a blog where they explain how to decrypt the response. I read the oasis specifications for the response xml schema. The response contains a reference to the x509 certificate that has the private key necessary to decrypt the session key, so then the body can be decrypted. According to the documentation of the service I am trying to consume, and pretty much everywhere I've read, I should use the private key of the certificate I used to sign my request, but I get an Exception saying the key is incorrect. I then tried every possible certificate with a private key in all my certificate stores to see if one of them would successfully decrypt the message but all of them failed. If I understand it right, this means the service expects me to decrypt the message with a private key I don't have. I'm rather new to WCF and web services themselves, so I might be missing something.
Do you know what could be happening? Or maybe I am understanding something wrong. Any help will be greatly appreciated.
Thanks
So, here is my million dollar question. I want to consume a service hosted by a third party, and therefore for the set up we exchanged X509 certificates. I sent them ours and we got theirs. I added their self signed certificate in the certificate store. Now, I have tried to connect to the services with soapUI, where i need to create a JKS file with my private key to connect, and use the WSSE headers for username, password, nonce and TTL and it works just fine.
But, I want to write a WCF c# client to communicate with the service, and adding my certificate to the client credentials in the config or through code does not work. Can someone please let me know how to use the private key for out going messages using WCF?
I have tried both these things, but not sure where am i going wrong...
proxy.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(#"C:\soapUI\soapUI\Agency1\certificates\myprivatekey.pfx", "Pwd");
proxy.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2(#"C:\soapUI\soapUI\Agency1\certificates\myprivatekey.pfx", "Pwd");
i have also added the correct wsu and wsse headers to the soap envelope. When i take the soap envelope from the WCF client to SOAPUI, it works, but not from WCF itself. So i am pretty sure its the difference in how the private keys are being used. So any line of thought will be helpful.
In this article, we will start with transport and message security understanding. We will then see simple code samples of how to implement transport and message security using WsHTTP bindings. We will also see the differences between ‘BasicHttpBinding’ and ‘WsHttpBinding’ with the help of a simple code. WCF security is a huge topic by itself, but I am sure with this article you will get a quick start of how to go about WCF security.
http://www.codeproject.com/Articles/36732/WCF-FAQ-Part-3-10-security-related-FAQ