I have a client application (windows service) which sends a request (WebClient.UploadString()) to a web service. I've created a certificate through IIS. This I attach to the WebClient before sending the request. However, I get the following message:
The remote certificate is invalid according to the validation procedure.
I believe this is referring to the server having an invalid certificate, but I am unsure of the best way to make the client trust the server. Eventaully, this web service will be installed on a number of servers as will the windows service so I can't attach the certificate to a single computer. Any ideas?
I don't know your exact situation/setup, but here is some general info on using self-signed certificates.
If you want to use a self-signed certificate you will need to add that certificate to the server's trusted root certificate store.
Basically the server does not trust the certificate used to sign your certificate, which is the certificate itself since it is self-signed.
As an alternative, you can create your own root certificate and add it to the server's trusted root, then use that to sign additional client certificates. This will make it easier because you won't have to install each client certificate on the server, just the root one used to do the signing.
Of course, you can always buy a certificate from a company (GoDaddy, Verisign, etc). These will be signed by a certificate that is already trusted.
Also, there might be ways to bypass the checking, but you probably don't want to do that.
Related
First of all I know that I have a lot of misconceptions about fundamentals of SSL.
But before, I want to give information about my goal; There is a Windows forms application written in C# and there is a asp.net WebApi that is integrated to this Windows app. Clients those are connecting to API are written in several programming languages. We need to add SSL somehow. this is not a public application and clients will build their client apps with the client certificate we will give them.
And here are lines of my knowledge about SSL those can be wrong or right;
-Self-Signed Certificates are more secure than bought ones. Becuase some known certificates can made unsecure by apps like Charles.
-For this scenario that i mentioned above as goal, there must be three certificates separately;
root cert,
a server side cert related to root cert,
a client side cert related to server cert.
-Every client can have same client side certificate.
-Visiual Studio Command Prompt is enough to create these certificates.
Also I need a source of documents to complete all these steps.
Self-Signed Certificates are more secure than bought ones.
nope ... self signed certs are just certs that a client can not verify on its own because there is no trusted third party saying: "this cert is ok"
you have to have your own way of securely delivering the cert to the client, possibly by having an admin manually installing them or bundling them with your app...
if you have no control over some of the clients, things tend to get ugly with self signed certs...
For this scenario, there must be three certificates separately;
root cert,
a server side cert related to root cert,
a client side cert related to server cert.
as far as i understood, you want x509 certs for SSL/TLS to authenticate the server and to avoid MITM attacks, not for client recognition by the server
in this kind of scenario you need only one certificate, or maybe two if you want to base your own PKI on this later ...
the case with one cert:
create a keypair and selfsign a x509 cert with that ... private key stays with your server, the public key will be included in the cert, which is shipped with your application and also handed out to other developers for their clients to authenticate the server...
this certificate will be required to be used in the client application to authenticate the server during SSL/TLS handshake
this is basically certificate pinning
darwback: depending on the size of the clientbase it will become challanging to replace this cert
case with 2 certs:
same as above, but the self signed cert is actually a root cert that can be used to sign other certs, in this use case in particular: the server cert...
the self signed root cert can then be used by the client to verify that the root cert was used to sign the server cert, which makes replacing the server cert easier ...
you might want to do the later and also setup a certificate revocation list in case you need to invalidate a cert ...
-Every client can have same client side certificate.
all the client needs is (as #john already pointed out) the self signed server cert (case 1) / self signed root cert (case 2)
-Visiual Studio Command Prompt is enough to create these certificates.
please notice that the documentation of makecert states "The Certificate Creation tool generates X.509 certificates for testing purposes only."
apparently this limitation was lifted ...
I think what you are after is called certificate pinning.
SSL certificates are used in the following way by default:
Certificate is issued by some authority. Client (browser, operating system such as Windows, Android etc) has a list of authorities it trusts. If certificate is valid (not expired, issued for domain we are connecting to etc) and is issued by trusted authority - all is fine
There are a ton of different authorities and client cannot trust them all. Instead, it trusts certain selected "root" authorities.
Those "root" authorities delegate ability to issue certificates to other, smaller, authorities, to which those root authorities themselves trust.
This might go on, so there is a chain of trust: certificate is issued by authority A, which is trusted by authority B, which is trusted by "root" authority, which in turn is trusted by client (your operating system).
That model has several weak points, one of them is list of "root" authorities your client trusts. Someone, like your corporate admin, or your government, or ISP provider, can install or force you to install custom certificate to your trusted "root" authorities list. Then it can perform man-in-the-middle attack by intercepting your SSL traffic and reencrypt it with this custom certificate that was installed to the trusted list.
That way client will think that all is still secure, while in reality your traffic is intercepted and responses are recorded and\or modified.
If you don't like this - you can use certificate pinning. Idea is simple - you just embed expected certificate for your api endpoint in your software.
By doing that you don't any more need to trust any authorities or verifying chain of trust above. All you need to verify is that certificate presented during SSL handshake is exactly the same as you embed into software.
For that reason - you don't really need certificate issued by some authority and you can use self-signed certificate.
So if you follow this path - issue self-signed certificate and embed it (without private key of course) to software (send to clients) and instruct them to verify your server certificate presented during SSL handshake is exactly this certificate.
Drawback is of course that if your certificate is compromised or expired - you need to update all software. It's not a big problem if said software is controlled by you, but it might be a problem if software is controlled by third party.
I'm curious to know why HttpWebRequest.ClientCertificates is a collection?
As far as I know, only one client certificate can be used (Is this merely true?) in client authentication.
An example of an application uses multiple client certificates, please?
While you can use only one leaf certificate for authentication you might want or need to send additional intermediate certificates so that the peer can build the trust path to the locally trusted CA certificate. This is true for both server and client certificates.
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 making the proxy server. The problem with HTTPS connections. I found that I need to generate the certificate for each host and put it to Trusted Root.
But for example Fiddler uses only one certificate for all connections. Maybe it generates selft-signed, but don't install to the Trusted Root.
Maybe I can download the certificate from the server and use it to speak with a browser?
Installing and uninstalling certificates takes a bit long time.
You need to use your root-CA certificate to sign the server certificate of the server you are spoofing. As long as the root-CA certificate is valid and trusted by your browser, your browser should not throw any errors. So you need your browser to trust only your root-CA certificate and not every server spoofed certificate.
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.