Fundamental of certificate based authentication - c#

I searched a lot and found many answer on how to implement certificate based authenticate in wcf. But my questions are related to fundamental of it.
While implementing Certificate based authentication on production, does client provides its certificate which server needs to add on its trusted people store? Or server provides a certificate (signed by server).
I guess while configuring wcf server, we just configure certificate location and store. We never bind it with any domain. So any client that present this certificate can access my service. And in case certificate needs to be bound to a domain. They why cannot we just allow all requests from that domain.
When client calls a wcf service, it present its certificate. Does this certificate only carry public key? And can this certificate by stolen (as it travels on network) and used by hacker to consume the web service.
I have idea about how ssl woks. In case of ssl, browser take care of all this stuff but in case of wcf service (when we want to allow only specific client to access our service) how it gets managed.
Thanks In advance.
Let me make it simple :
I want to create a web service and i want that three clients (A, B and C) can use it. I want to authenticate these three clients by certificate. While setting up, do these clients need to send their certificates to me. Or I have to create certificate for them? Will client share their private key as well (while setting up)
Do I need to put these certificates into trusted people store?
When they request for webservice, they will present their certificate (with public key only). If they present it with public key only, hackers can steal this public key and request for my web service. How will my webservice distinguish between hacker/actual client.

While implementing Certificate based authentication on production, does client provides its certificate which server needs to add on its trusted people store? Or server provides a certificate (signed by server).
In a secure service, a server certificate is mandatory. Client certificate is optional. The server can be configured to ignore, accept, or require client certificates.
I guess while configuring wcf server, we just configure certificate location and store. We never bind it with any domain. So any client that present this certificate can access my service. And in case certificate needs to be bound to a domain. They why cannot we just allow all requests from that domain.
Not sure how you'd bind to a domain without a client certificate. You mean with reverse DNS lookup? That requires an IP address, and a malicious user can spoof it.
The typical means of restricting access via client certificates it to map one of the fields in the client certificate (typically the subject or domain) to a user account. You can have one-to-one mappings (each client certificate represents a single user) or many-to-one mappings (if the client has a certificate that is in a list, he is treated as a certain user). If the certificate isn't mapped, the user is treated as anonymous. More information here assuming you are using IIS.
When client calls a wcf service, it present its certificate. Does this certificate only carry public key? And can this certificate by stolen (as it travels on network) and used by hacker to consume the web service.
The certificate FILE that you handle during setup contains both the public and private key. The certificate itself is contained in that file; it contains a payload that includes the public key and a MAC signature, but does not include the private key.
The private key is put into secure storage and is never sent in any HTTP request. Only the certificate (and its public key) are sent over the wire. The whole file is not sent.
Edit to Respond to Further Questions
I want to create a web service and i want that three clients (A, B and C) can use it. I want to authenticate these three clients by certificate. While setting up, do these clients need to send their certificates to me. Or I have to create certificate for them?
During set up, a client certificate must be generated by a certificate authority (CA). You can actually serve the role as an intermediate CA (for production certificates) who derives his authority from a root CA (such as Verisign). In order to do that you must request a certificate from the root authority. They will issue you a certificate with its own public key, and give you a private key, so that you will have the ability to generate and digitally sign certificates of your own. You typically have to pay for this privilege.
In addition, you can become your own root CA! This is common during the development phase. Basically you generate your own public and private keys and start generating your own certificates. These are called self-signed certificates. The down side of being your own CA is that nobody will recognize your public key, so in order for anybody to use your certificates they would you have manually add you to their list of trusted root authorities.
Will client share their private key as well (while setting up)
No, nobody ever shares a private key with anybody, throughout the entire PKI. Ever. This is exactly why it is referred to as a private key. The only exception is when you are a certificate authority and you are generating a private key in order to create a certificate. In this case the private key must be carefully guarded during handling. It is never, ever sent over the wire as part of SSL communications.
Do I need to put these certificates into trusted people store?
Yes and no. If you are using a self-signed certificate, yes. If you are using a certificate that was signed by an CA that in turn has a certificate that was signed by a root CA, the root CA must also be in the list of trusted root authorities, but you probably don't have to add it. It should be there automatically. That is the whole purpose of using trusted root authorities-- everybody is supposed to know about them and should recognize their public keys. Root certificates are typically distributed to browsers automatically during installation and kept up to date using the browser's patch and update services.
When they request for webservice, they will present their certificate (with public key only). If they present it with public key only, hackers can steal this public key and request for my web service. How will my webservice distinguish between hacker/actual client.
This is a great question.
It's important to recognize that an SSL handshake includes a lot more than sharing certificates. There is also, among other things, a challenge/response step. Here's how it works:
Your server will generate a random number or time stamp ("challenge") and send it to your browser, challenging it to encrypt it. The browser will then encrypt the challenge using the private key (which it only has access to). This "response" is then sent back to the server for verification. The server uses the public key from the client certificate to decrypt the response. Since only the client has the private key, and since the public key is publicly known and verifiable (because it is contained in a signed and tamperproof certificate), the server can tell that the response had to have been encrypted by the client associated with the certificate. And because the challenge was generated by the server, and is different every time, a hacker cannot impersonate the client by replaying the response from a previous challenge.

While implementing Certificate based authentication on production, does client provides its certificate which server needs to add on its trusted people store?
Yes, if the server asks for it, otherwise no.
Or server provides a certificate (signed by server).
Always. These aren't mutually exclusive. Both can happen.
I guess while configuring wcf server, we just configure certificate location and store. We never bind it with any domain. So any client that present this certificate can access my service. And in case certificate needs to be bound to a domain. They why cannot we just allow all requests from that domain.
I can't make head or tail of any of that.
When client calls a wcf service, it present its certificate.
If the server asks for it.
Does this certificate only carry public key?
Yes.
And can this certificate by stolen (as it travels on network) and used by hacker to consume the web service.
No, because it only contains the public key.
EDIT Re 'Let me make it simple':
While setting up, do these clients need to send their certificates to me.
Only if they are self-signed.
Or I have to create certificate for them?
That's another possibility, but then you would have to become a mini-CA (Certificate Authority). Too broad.
Will client share their private key as well (while setting up)
Definitely not.
Do I need to put these certificates into trusted people store?
There is no such thing as a 'trusted people store'. There is a trusted certificate store, which usually only contains CA certificates. You only need to add the actual client certificates if they are self-signed. You might need to add their CA certificate if it isn't already there.
When they request for webservice, they will present their certificate (with public key only). If they present it with public key only, hackers can steal this public key and request for my web service.
I've already answered that. No.
How will my webservice distinguish between hacker/actual client.
They won't 'just' present their certificate: they will also provide a digital signature over it signed by their private key. Possesion of the certificate alone is worthless to an attacker. Without the private key they cannot even get past the TLS handshake. Your web service won't even see them.

Related

How do I programmatically find whether the intermediate certificate was served by the web server?

My C# code uses HttpWebRequest to send requests to a web service via HTTP over SSL (https:// prefixed URLs). The service has it's coolservice.example.com certificate which is signed by certificate authority intermediate certificate which is in turn signed by the trusted root certificate authority certificate. The latter must be in the caller certificate store and marked as "trusted root", otherwise all that SSL trust chain thing makes no sense. However the intermediate certificate may come from either of the different sources:
the web server may serve it together with its own certificate (as in "here's my certificate and btw it was signed with this certificate which was signed with something you likely trust, please just check the signatures along the trust chain")
the caller may automagically retrieve the intermediate from the certificate authority (AIA protocol or something) - I know this because I've been interfacing with a web service which didn't have the intermediate certificate installed and "it just worked"
the caller may have the intermediate certificate installed in their store
I need to check that the web server properly serves (not only has in the trust store but actually serves the certificate) the intermediate while the SSL handshake is in progress. This test site even shows "sent by server" next to the intermediate. So I guess such check is possible.
How do I craft such a check with C# and .NET Framework?
So far I've only come across HttpWebRequest.ServerCertificateValidationCallback which accepts the web service certificate (X509Certificate object) and the trust chain (X509Chain object). The trust chain lists all the certificates in the chain however I cannot see anything detailing where the certificate was obtained.
How I programmatically find whether the intermediate certificate was server by the web server or it was obtained from elsewhere?

How to revoke a client certificate in WCF?

I'm developing a self-hosting WCF Service with this scenario:
wsHttpbinding
*Transport security layer
Client Credential = Certificate
I created a self-signed RootCA certificate and a "www.server.com" and a "www.client.com" certificates issued by the RootCA certificate.
This is the client environment configuration:
I need to install the RootCA public key in the Trusted Root Certification Authorities store and the www.client.com certificate in My store.
Like this everything is working.
But my question is, in this scenario described in MSDN example the www.client.com public key should not be in the TrustedPeople store of the server machine too? Because if I want to exclude a client I should have the control on the server side. Theres some configuration on WCF that allow me do that?
ps: In the MSDN link above, in the first paragraph theres this quote The server’s certificate must be trusted by the client and the client’s certificate must be trusted by the server. But this is not working.
I think that in order to fully control client authentication with certificates, you likely need to fully understand the certificate revocation process. The following article provides a good overview of Certificate Revocation, including the validation chain and CRL caching.
http://technet.microsoft.com/en-us/library/ee619754(v=ws.10).aspx
Regarding WCF configuration, you have access to the following config values that control client certificate validation:
X509ClientCertificateAuthentication.RevocationMode
X509ServiceCertificateAuthentication.CertificateValidationMode
http://msdn.microsoft.com/en-us/library/system.servicemodel.security.x509clientcertificateauthentication.revocationmode(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/system.servicemodel.security.x509servicecertificateauthentication.certificatevalidationmode(v=vs.110).aspx
Regards.

Is there a security bug in MY wcf application?

I did wcf username/password authentication to my SOA application. Security model is Message, and the key is a x509 certificate encrypted RSA 4096 bits. Every client has the same key in config file
<certificate encodedValue="VeryVeryBigRsaKey />
I am curious if for example one application user, having the VeryVeryBigRsaKey can sniff the packets of other users, that share the same key (VeryVeryBigRsaKey). If yes i think is a very serious issue, and i have to change the security model to TransportWithMessageCredential.
EDIT:
I generated my key using pluralsight self cert, and exported it into a *.cer file with Base 64 encoding. And opened generated *.cer with notepad, and that gave me the rsa key (VeryVeryBigRsaKey) :)
I think you mean you use the UserName credential type and the < certificate > is used to identify the server so that client can trust it gets the message from the correct server.
if another user wants to sniff the package, he needs the server certificate that can only be owned by the real server.
Therefore, your concern is no reason.
The configuration you refer to is I think in the endpoint identity element. If so, this represents the identity of the service, which the client stack will check before communicating with the server. It therefore has to be the same on every client.
The keys used to secure message traffic are derived from the client credentials. Your fears based on this certificate identity are groundless.
I'm sure there is a security bug in WCF but this isn't it.
The certificate is used to
a) verify the server
b) encrypt a client-generated symmetric key and send it to the server
Another client can not break in to this.

Authenticating a Server with Digital Signatures

I understand how Non-repudiation and Integrity are achieved with Digital Signatures, but it's the Authentication that I don't grasp yet.
I'm developing a Client-Server application in C#, that should be capable of Authentication with Digital Certificates and Digital Signatures. I know how to check the validity and integrity of a Signature (with SignedCms.CheckSignature()), but how does this authenticates any of the parts involved?
For example:
The client asks the Server for a Digital Signature,
The client receives the signature and validates it,
If the validation succeeds, continue.
The client could be a victim of a man-in-the middle attack and receive a valid signature in step 2. The validation would succeed, but the client wouldn't be talking to the right server.
What am I missing?
You're missing trust of the signing certificate.
Consider SSL certificates, they have a signing path to a root CA which is trusted by Windows (or whatever OS). If the MITM presents a self signed cert, or one produced by an untrusted CA then it gets rejected by the browser and a warning is displayed. So a certificate is only trusted if it's issued by a CA that you know, or chains up to one you know.
For self signed certs it becomes more complicated, you need to securely exchange the key fingerprint, serial number or other constant identifier and validate that the signing key is in fact one you expect - one reason why self signed certs generally shouldn't be used for public facing web sites or other services.
So if there's an MITM attack, and the signature from the original machine is stripped, the message changed, and then resigned using an unknown certificate as long as you check the identity of the signing cert against something you trust then you'll reject the resigned message.
(in reality it gets more complicated, but you get the point I hope)
They could only receive a valid signature if the man in the middle possesses the private key with which to sign the request. I think the key thing you may be missing is that altering any aspect of the item which is digitally signed would invalidate the signature. The man in the middle can re-submit the request, but if they change it, the signature validation will fail.

Comparison of the relative merits and appropriate scenarios for the supported WCF authentication credentials

I'm trying to select the correct authentication mechanism for a WCF service. This article explains what the supported credentials are - I just don't understand how to decide between them.
Please could somebody supply an explanation of when each of the authentication options are appropriate to use, and the advantages/disadvantages of each over the others.
For reference, the authentication options are:
None
Basic
Digest
Ntlm
Windows
Certificate
Password
Note: I have seen a great MSDN article on this, but I cannot for the life of me find it anymore.
None:
Pretty straightforward - use this when you don't want to identify or authenticate your users.
Basic and Digest:
These authentication types aren't used much any more, but occasionally you might need to connect to an older web service hosted in IIS, which might be configured to use Basic or Digest authentication. Traffic won't be encrypted. For Basic, the password will be sent in plain text, and for Digest the password will be sent in a poorly encrypted form. Avoid using these authentication types.
NTLM and Windows:
NTLM uses the NT LAN Manager to control security. Windows, by default, will use Kerberos (ie Active Directory) to control security. If Kerberos is not available, it will default to NTLM. Only use NTLM if you specifically need to avoid Kerberos (I cannot think of a scenario where you would want to do this, but part of WCFs greatness is its flexibility).
Certificate:
If your users have their own certificates which can be used to identify them, you might consider using this authentication mode. Passwords can be guessed - it is very hard to guess a certificate, so this is a pretty secure mode of authentication (provided the certificate itself is secure).
Password:
Use Password when you want to create your own method of validating a users username and password. This might involve accessing an existing user credential store in a custom database. You will need to write your own UserNamePasswordValidator - example at http://nayyeri.net/custom-username-and-password-authentication-in-wcf-3-5.
To summarize, I usually choose Windows as the authentication mode. It is secure and simple and works for most people in an enterprise environment. If you're creating a new service and for some reason Windows cannot be used, go for Certificate or Password. If you're hooking into an older SOAP service hosted in IIS, you may need to look at using None, Basic or Digest.
Although I asked this question I will add what I know about Certificates as this is something I have worked with - though if my understanding is imperfect, I'd be happy to be corrected.
An X.509 certificate consists of a Public Key and a Private Key and issued by a trusted Certificate Authority (you can self-sign a certificate, this limits the usefulness of the certificate to trusted sources only). The CA will charge a fee for the certificate, and it will expire after a period of time.
The Public Key does not need to be protected and is given to the server. The Private Key is kept private and is used by the client. Messages encrypted by the Private Key can be decrypted by the Public Key.
A request from a client has a digital signature embedded in the SOAP. This is generated using the Private Key. When the server receives the request, it uses the Public Key to read the signature. If the signature can be read, then the request is considered genuine.
Within Active Directory, there is a mechanism whereby an X.509 certificate can be mapped to a user account, so you can impersonate a user with a certain permission set based on the X.509 authentication.
The benefits of X.509, are:
that it can be used across domains; and
that the Private Key can be securely stored in the client's Certificate Store. So there is no .config file containing credentials.
Failure to control the distribution and storage of a Private Key is akin to writing a username/password on a post-it note and sticking it on your monitor.

Categories