I am trying to send an X509Certificate from an Http Handler to a web service that will receive and read the certificate to authenticate the user. I know the certificate is sending fine; I have a tester that lets me look at the HttpWebRequest before sending, and the ClientCertificates property shows that it has a certificate attached. (e.g. request.ClientCertificates.Count = 1).
However, on the other side on the web service, HttpRequest.ClientCertificate is consistently showing NULL. I have looked at a number of Microsoft KB examples and all of them are using the same technique for inserting the certificate. Other unrelated articles show that HttpRequest.ClientCertificate is the preferred way of reading it in.
So what am I doing wrong, and how can I determine on the server that a client certificate was sent?
Perhaps configuring your HttpListener with clientcertnegotiation=enable with netsh would help (this makes the server negotiate the client-certificate during the initial handshake, as opposed to using re-negotiation).
It may also depend on whether you've initialised the certificate on the client side with its private key, see Can't connect to HTTPS using X509 client certificate
Related
We have been trying to solve an issue for a while.
We consume a web service with client certificates.
Service owners gave us a .p12 file, it contains the client certificate and CA and private key.
We can see the certification path from the certificate itself.
The issue is, when we try to call the web service via SOAP UI, it works. In SOAPUI we chose the .p12 file as keystore and set the password. It works.
When we try to call the web service via our .net client application, it does not work.
--this is how we call the web service
channelFactory = new ChannelFactory<AcquisitionAutorisationService>(binding, serviceAddress);
channelFactory.Credentials.ClientCertificate.Certificate = new X509Certificate2();
channelFactory.Credentials.ClientCertificate.Certificate.Import(#"C:\cert\abc.p12", "password", X509KeyStorageFlags.DefaultKeySet);
When we monitor the packages with WireShark, we saw that, SOAPUI sends two certificates both client certificate and certificate authority in the request.
But .Net client sends only the client certificate not CA. So firewall of the server does not allow our calls.
So my question is how come we managed to send the CA root with our request like SOAP UI, in .Net?
If anyone can give any idea about the issue, I would be appreciated!
If the first client (SOAP UI) is sending the CA certificate, then it must be an intermediate CA certificate that is itself signed by another CA. A client would not have any reason to send a root CA certificate.
It could be as simple as installing the intermediate CA certificate on the server so that the second client need not send it.
It could also be as simple as installing the intermediate CA certificate on the client in the Windows certificate store for the local machine (or user), so that it is available when the client certificate chain is built.
Otherwise, I am pretty sure what you are looking for is how to get .NET to send the intermediate CA certificate in the client certificate chain.
I am using u web service developed in wcf. And it has made secured using digital certificate.
The data decrypted at client side itself.
I found that it does "man-in-the-middle" approach to do the same.
But I could not get a explanation about how to block HTTPS analyser to decrypt the data.
Can anyone help me with some code or link?
If you want to prevent a man-in-the-middle attack, you need to ensure that the SSL certificate is trustworthy. If the https traffic can be intercepted then either the SSL certificate isn't from a trusted source, or the analyser has access to the private key.
If you want to learn more and see how it works, have a look at this post about Fiddler. Fiddler acts as web proxy and can be configured to decrypt https using man-in-the-middle.
Why make use of HTTPS when Fiddler can decrypt it
I am having a lot of trouble setting up an X509 certificate scheme in C#.NET. SSL is enabled on the server and the connection is being made over SSL. Certificates are being added to the request's store via request.ClientCertificates.Add(). However, no client certificate is being attached to the handshake request (which I am both confirming by both checking the server's code through HttpRequest.ClientCertificate and by analyzing the handshake in Fiddler).
As nearly as I can tell, the problem here is that the server is not requesting a client certificate. The certificates are definitely in the outgoing request, but I see none on the handshake and none on the server side - they simply disappear into the ether. I'm aware of the semantics behind choosing a certificate (thanks to this page), but it hasn't resolved my problem. The CAs should be the same; I am using the same self-signed, private key secured certificate for each end of the test.
Apparantly I can use certutil.exe to check which certificates will be chosen when used with a given server certificate. This would be a huge help if I could figure out how to use it like this. Certutil is a big program that is poorly documented. Any help would be appreciated.
If you're using IIS serverside you MUST provide certificate that is trusted by your server. So you MUST add client cert' CA cert into server computer 'Root certificate authorities' storage. IIS doesnt work with self-signed certificates. It requests client cert providing list of CAs it trusts to.
Here is a scenario:
Desktop application
Installed from the web
Needs to call a WCF webservice
Transferred data needs to be encrypted from Client to Server and Server to Client
Is there a well understood solution for this that is:
Secure
Easy to manage and deploy
I guess what this comes down to firstly is whether https encryption happens in both directions... Does it? Or do you need mutual authentication for that?
Try using HTTP over SSL
HTTPS is what you're after - it does provide end-to-end encryption (client-to-server and server-to-client).
So long as you can generate and install a server certificate, and be sure that your clients 'trust' the issuing authority of your certificate, then you're good to go. Note that this is not mutual authentication - your clients know that they have contacted the correct server, but the server does not know who has contacted it.
It can offer mutual authentication through the use of client-side certificates, but I would argue that does not fall under the 'easy to deploy' requirement.
HTTPS works...
I was confusing Encryption with Authentication and they are two different things. Simple Https which is the most common only authenticates the server to the client which is sufficient in many cases. An additional step (where the client also has a certificate) can be required to authenticate the client to the server but this is not required. In both scenarios, data with Https is encrypted from both the server to the client and client to the server using a session key once the SSL handshake has been completed. This is all described here:
Description of the Secure Sockets Layer (SSL) Handshake
I'd like to use client certificates to verify the identity of administrative callers to my web service. Then I can issue certificates only to the people I want to call my web service and be pretty sure noone else can call it. This is in a very controlled scenario where only one or two people will get the client certificate, so distribution isn't a hard problem.
This article provides a good example of how to call a web service using a client certificate.
But how can I check details of the client certificate from within my web service? This old article talks about configuring IIS to do it, but I'd like to do it programmatically within my app. I think?
thanks for any suggestions!
The incoming Request has a ClientCertificates collection that you can interrogate -- you can check the various fields in the cert or check the actual raw byte data (perhaps against a datastore or other source) if you want to completely validate it.
Note, if you issue the certs from your own private CA, you will need to install the CA's cert on your webserver into a store that is visible to all users, otherwise IIS won't request those certs from the user (due to the nature of how the server/client interaction works.)