Using client certificates in .NET part 1: introduction
January 11, 2016 Leave a comment
Digital certificates play a crucial role in web security. If you work as a web developer then you’ve probably come across at least some security related project where you had to deal with certificates in code.
Certificates come in a couple of different versions depending on their function, the most pervasive of which probably being server side ones for SSL connections. We’ve gone through server side certificates in some detail before on this blog starting here. In this series we’ll concentrate on client certificates and see what role they can play in web security. Most of the material on server side certificates, especially the first 2 posts are also relevant for this discussion.
It’s important to note already now that you can combine a number of security levels and solutions in your projects:
- You can have the traditional forms based authentication. You can read about it on this blog here and here.
- Custom authentication. Here‘s a series dedicated to custom auth in Web API 2 as an OWIN/Katana component
- Server-side certificates, see the reference above
- Client-side certificates, to be discussed in this series
- Various techniques related to cryptography, such as asymmetric encryption. You can check out the section called “Security and cryptography” on this page for inspiration.
…and there are probably many more options not listed here. The point is that these techniques can be combined, you are not restricted to just using one of them.
Certificates in general
Certificates in general, server and client side and other types – X.509 certificates to be exact – are not some complex objects but simple files stored on the file system. Chances are that even your PC has a large number of certificates stored in designated folders. The certificates snap-in can be used to view them. This page on MSDN describes how to open the snap-in, it’s really simple.
All certificates have a number of common properties. Once you have the snap-in open you can double-click on a certificate to view its content:
A certificate has a large number of properties but probably the most important ones are the following:
- Issued to: if the certificate is used for TLS communication then this is a domain name like amazon.com. That domain is the owner of the certificate
- Issued by: in order to create a trusted web server environment the certificate must be issued by a trusted certificate authority (CA) such as Symantec or Go Daddy. The relationship between a certificate and a CA can be likened to your travel passport and the authority that issued that passport, e.g. the ministry of interior or the police. The example in the above screenshot shows that the certificate was issued by myself to myself, i.e. it’s a so-called self-signed certificate. It’s nice that I trust myself but the above certificate could never be used for real life HTTPS. I’m not a trusted CA. Also, a significant portion of Earth’s population doesn’t know me and probably wouldn’t trust me with their credit card numbers. However, self-signed certificates are great for testing purposes. You might not want to pay for a real certificate just to test some code. The DigiCert homepage shows an example of what a certificate can cost per year.
- Validity dates: a certificate has start and expiry date. Outside those limits the certificate cannot be used for server authentication
- Public key: the public key part of an asymmetric public/private key pair
Each certificate has also one or more purpose as listed under the “This certificate is intended for the following purpose(s)” section. That list defines what you can do with a certificate. E.g. a certificate used for code signing cannot be used for server verification.
What is the public key? If you open the Details tab in the Certificate window you’ll find a property called Public key with some long byte content:
Public and private key pairs are the two most important ingredients in asymmetric encryption and digital signatures. If you are new to these topics then I have dedicated some detailed posts to them where you can start, I won’t repeat all the details here:
- Introduction to asymmetric encryption in .NET cryptography
- Introduction to digital signatures in .NET cryptography
Server side versus client side certificates
As the name suggests server side certificates are files stored on a web server. They are used by the web site to identify itself and encrypt the communication between the server and the client. Modern browsers are equipped with tools to handle certificates. If you navigate to twitter.com you’ll see that the server certificate has been verified:
You can normally find out more about the certificate. The way to do this depends on the browser but you should be able to just click the information in green and select to view more details. This is an excerpt of what Firefox can show about Twitter’s certificate:
For more details on server side certificates you can read through the series referred to above.
Client certificates on the other hand are located at the client. They are used to strongly authenticate the requester. It’s similar to a passport that you show when travelling abroad. You identify yourself with the passport or some other ID. If the immigration officer trusts its validity and contents then you are allowed to enter, otherwise you need to return to where you came from.
Client certificates play a similar role. Certain web sites require the client to send a client certificate along with the web request. The certificate is verified and then either rejected or approved. If it’s rejected then you won’t be able to view the web site content. In other scenarios you may proceed to the web site but you won’t get access to all its features. Here’s how Wikipedia defines client certificates:
“A client certificate is a type of digital certificate that is used by client systems to make authenticated requests to a remote server. Client certificates play a key role in many mutual authentication designs, providing strong assurances of a requester’s identity.”
E.g. you might have a business with a number of authorised partners. Only authorised partners are allowed to order certain items from your web site. One option to tighten security is that each partner must have a client certificate that they must attach to every request. If they can produce the certificate then they will see the “order items here” section. Otherwise anonymous users will only see a generic partner sign-up link.
You can have various levels of accepting client certificates in your application:
- You can ignore them completely
- You can accept them and then decide what to do with them, e.g. provide extra features for those that can strongly identify themselves
- You can also require client certs, i.e. you may reject all requests that lack a certificate
You can set these options in IIS:
You can also modify the web configuration file and a security element to the system.webServer section. The “access” node of the security section can be configured to accept client certificates. You can read more on the access flag and its properties here and here on MDSN but here comes an example:
<security> <access sslFlags="Ssl, SslNegotiateCert" /> </security>
The above snippet means that SSL is required, i.e. HTTPS must be used, and client certificates are accepted, though not required.
Here’s another example which requires client certificates but not SSL:
<security> <access sslFlags="SslRequireCert" /> </security>
Note that these are IIS features. We’ll take a look at how to use client certificates in code in Owin/Katana later on. In that environment it’s possible to mimic the behaviour of the access SSL flags in code instead.
In the next part we’ll manually create a test client certificate.
You can view the list of posts on Security and Cryptography here.