I've been planning to write this for a while now, and finally have a bit of spare time to hopefully be able to write something which will help others.
When people come across certificates, it often appears to be some sort of black magic. I would know, I used to be one of these very people. But in reality once you have a firm grasp of the basic concepts of certificates, they are not that complicated. The purpose of this post to hopefully help bridge this gap and provide a means to allow others a better understanding of certificates and how they play a role in security.
Ultimately all certificates are used as part of a cryptographic function. That is not to say all cryptographic functions involve certificates, however you will not find a certificate which is being used outside of some form of cryptographic function. These functions typically only boil down to 2 types:
- Public-key encryption
- Some form of cryptographic signing - typically used to validate something or someone
I'm going to touch on the public key, since this is an underlying foundation to typical certificates (at least all certificates which are used for web sites as well as digital signatures). As the name suggests there is a public key. Now this notion of a key being public may seem as weird, but it is still as the name suggests. The key is meant to be publicly shared, scary right? Well not quite, there is an associated private key. This key has to be kept private, as the name suggests. This private key is used by the key holder to perform that sensitive cryptographic functions (more on this later).
For this post I will only focus on X.509 certificates. These are by far your most common defining format of certificates. X.509 certificates are also available in different formats:
For the structure of a X.509 certificate I will only focus on v3, since again these are going to be vastly the majority which you will encounter.
v3 certificates have the basic structure of:
- Version: 3 (0x2)
- Serial Number
- Signature Algorithm
- Validity period
- Not Before
- Not After
- Subject Public Key Info
- Public Key Algorithm (along with the public key)
- X509v3 extensions (optional)
- Signature Algorithm (along with signature)
For example the current (at the time of writing this post) X.509 certificate for https://www.google.co.uk looks like:
Certificate: Data: Version: 3 (0x2) Serial Number: 4627240520293488349 (0x403742bcae6316dd) Signature Algorithm: sha256WithRSAEncryption Issuer: C = US, O = Google Trust Services, CN = Google Internet Authority G3 Validity Not Before: Jan 8 08:21:00 2019 GMT Not After : Apr 2 08:21:00 2019 GMT Subject: C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.co.uk Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: 00:bf:61:25:16:ec:a4:63:9e:f6:41:37:6f:34:3c: 51:92:99:04:c7:87:bc:1a:41:16:69:51:87:03:40: 41:3b:c9:10:50:d4:77:a4:45:34:e9:04:e8:b9:73: c1:f4:08:47:78:e9:87:ce:87:e7:df:06:f2:79:c8: eb:ac:3e:a7:c8:0d:c3:6c:39:21:67:3d:5a:45:cc: 7f:fa:5a:4b:33:46:c9:e7:28:d1:06:34:ad:4a:07: e4:23:31:d1:6d:02:fb:51:4b:f8:88:41:6c:9f:ca: 37:c5:8b:f1:31:2e:b2:7c:8f:5d:27:76:fb:20:c5: 28:b7:b9:4e:fd:b4:35:d2:07:24:74:cd:16:e2:b0: 5e:54:3c:30:b0:94:8e:b3:be:55:7b:13:92:7f:9e: 6d:8f:f8:8a:b7:1f:75:24:7e:19:aa:08:a1:fa:8b: 00:e8:94:b9:b8:c8:3e:3d:6d:97:b3:4f:68:af:1f: 84:5c:fc:57:c2:29:dc:3f:d5:e5:40:89:02:17:ec: 0e:da:10:55:a1:83:ca:1a:cf:66:3a:04:5c:06:94: 79:6c:4d:5d:10:1c:0b:4f:8c:e5:a1:18:59:f2:95: b3:10:aa:aa:9e:ed:14:bf:ec:cd:2d:3f:48:79:20: 75:31:5f:80:63:25:e9:b1:66:f7:1b:87:d5:5d:7e: a5:d5 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Subject Alternative Name: DNS:www.google.co.uk Authority Information Access: CA Issuers - URI:http://pki.goog/gsr2/GTSGIAG3.crt OCSP - URI:http://ocsp.pki.goog/GTSGIAG3 X509v3 Subject Key Identifier: C7:9D:97:8A:E7:66:86:51:85:85:9E:DE:CB:33:24:55:42:9F:7B:A6 X509v3 Basic Constraints: critical CA:FALSE X509v3 Authority Key Identifier: keyid:77:C2:B8:50:9A:67:76:76:B1:2D:C2:86:D0:83:A0:7E:A6:7E:BA:4B X509v3 Certificate Policies: Policy: 126.96.36.199.4.1.11188.8.131.52 Policy: 184.108.40.206.2.2 X509v3 CRL Distribution Points: Full Name: URI:http://crl.pki.goog/GTSGIAG3.crl Signature Algorithm: sha256WithRSAEncryption 83:63:9c:e8:a7:10:29:16:d0:ee:10:71:e5:ae:71:77:9c:93: 05:aa:d7:fd:8a:13:09:46:bd:86:2c:e8:c4:45:6b:12:f3:b2: 8f:93:fb:53:a4:c0:55:f6:9a:2d:5d:6f:40:89:84:16:af:e4: 0e:f7:07:ef:80:08:87:c1:61:09:7b:3b:13:0b:1c:a2:97:bc: af:00:df:7c:0a:f3:b7:d3:4a:e9:a9:c4:13:b7:29:d6:55:79: 63:dc:e3:25:75:a0:1d:cc:2c:54:80:27:a1:d5:76:84:3e:39: b3:6e:dd:3b:7d:12:12:08:12:d6:c2:e5:9f:28:dc:f7:1e:8d: d7:4a:0b:23:7c:9f:c0:43:7e:00:e3:d8:5c:c1:ef:8a:52:47: 82:66:fd:53:dc:b2:e9:d2:50:3a:c7:dd:0f:f6:83:ef:c4:02: d7:df:03:74:e3:c1:71:3e:bc:f8:4a:ae:ef:83:0d:5c:0e:c2: 79:24:2b:52:a6:67:fb:95:2c:0e:68:28:5a:f2:d7:bb:b4:b3: 3d:ce:95:5c:a1:c5:d8:43:70:fd:0d:85:6f:ea:e7:23:35:1b: f3:ce:95:4a:0a:54:d6:a4:18:18:90:d3:91:94:6b:3b:b4:af: 4a:a9:5e:eb:83:f1:a2:97:56:c5:d9:a0:28:87:62:0d:a8:84: 09:d2:f3:62
The process of generating a certificate involves several steps:
- Generate the private key which will be used for the certificate.
- Generate a Certificate Signing Request (CSR), using the private key. This includes all the details from the requester which will be included in the certificate, such as Subject information (name, email address, organization, etc).
- Post the CSR to a CA (more on this below), and obtain the certificate back from the CA.
The process of generating a certificate from a CSR involves the private key for the CA. This means that a CA is nothing more than a glorified certificate! In fact CA's are certificates, where one could view them simply as signing certificates (they are differentiation by the X509v3 Extended Key Usage field having an entry of Certificate Sign, as well as the X509v3 Basic Constraints: critical field having a value of CA:TRUE).
Chain of Trust
Now there is a problem. What is stopping me from simply trying to create my own certificate for an existing site, which I have no authority over (for example www.google.com)? Well this is where the notion of a Certificate Authority comes into play. Certificate Authorities, or CA's, are organizations which the consumer of the certificate (say a user browsing to a site) has placed a form of trust in, to ensure that certificates are only issued to those authorized to do so.
It so happens that many software vendors and applications, such as web browsers and Operating Systems, have already vetted (and consistently do so) a list of CA's whom they deem to be trust worthy. This list forms what sometimes referred to as a trust store. This is simply a list of CA certificate (and hence the public keys of the CAs). The application will then use the public key of the CA to ensure that the presented certificate was signed by the private key of the CA (which it trusts).
The chain of trust notion comes into the fact that a CA is nothing more than a glorified certificate. This means that a CA can (and in fact do) generate another certificate which in turn itself could become a CA. So what you end up having a hierarchical structure for trust. Form example if you have a look at the certificate for https://www.google.co.uk again (taken from a SSL Labs scan):
You will see that the server certificate has been signed by CA named Google Internet Authority G3 and that CA has been generated from (it's certificate signed by) a CA named GlobalSign. Also interesting in the above image we notice that the scan trusted all the certificates.
The magic of all of this is if I trust the top level CA, I will then trust ALL certificates generated by that CA, including any certificates generated by children CAs (so long at the application can validate the full chain back up to the root). Some terminology you might hear regarding this is a root CA (the top level or root level CA) and subordinate CAs (or children CAs, CA's generated from the root CA).
Most clients also have the option to explicitly trust a certificate itself. This is typically done when one uses a self-signed certificate.
I briefly touched on certificate validation above, in terms of a client validating that a certificate has been signed by a trusted CA. How does this actually work? Well when a CA generates a certificate from a CSR, it signs the certificate with it's own private key. And since only this CA should only ever have this private key, only this CA can generate that signature. When a client wishes to validate the certificate it, will take the public key of the CA (from the CA's certificate), and ensure that the signature on the certificate which it is validating is valid. I won't go into the details, but this is the basic principle of signing with a private key and then validating with the public key. If a different private key (and hence different CA) was used to generate the signature, then validation will fail with using the non-matching public key. Another key feature of this process is to ensure that the certificate has not been tampered with. Otherwise a malicious actor could simply change a certificate which they obtained legitimately to fit their needs. For example they could request a certificate to evil.eve.com and simply alter the certificate to become for www.google.com
This is pretty obvious so I won't go into much detail. The validity fields on the certificate (not before and not after) need to be validated to ensure that the certificate is still valid. This is becoming more and more important since certificate revocation is not in a particularly good state at the moment.
Common Name and Subject Alternative Name
Validating the Common Name (CN) and/or Subject Alternative Name (SAN) are a requirement of a server certificate. For secure connections you not only want to prevent someone from tampering with or spying on what you a sending and receiving from a server, but you need to validate that you are indeed communicating with the intended server.
For client certificates, this depends on the server and it's implementation. For signing certificates this will only be meta-data and is not all that important for the signing process.
When validating the CN or SAN, the client will need to ensure that:
- If a DNS entry is in the SAN, that one of the entries matches the hostname of the certificate for the server which it is connecting to.
- If no entry exists, then the client will look to the CN field.
Wildcards allow for many domains to be associated with a single certificate. However this carries its own risks and is something which I advise against. Also I've notice that some clients are now only looking at the SAN field and are not longer looking at the CN field at all.
Yes certificate are perhaps a bit confusing and scary at first, but once you boil them down to their basic components and abstract away some of the complexities that they have associated with them (such as the maths and cryptography), they are not all at that difficult to understand. Hopefully this post will hope some have a better understanding of certificates and how they work.
Do's & Don'ts
- Don't share a certificate's private key. If this is compromised the certificate becomes worthless from a security perspective.
- Do validate certificates:
- Signed by a trusted CA.
- For server certificates the hostname of the server appears in the CN field or as a DNS entry in the SAN field.
- Validate that the certificate has not expired.
- Don't blindly trust CA's. Ensure that the CA is a reputable CA and one which can be trusted to follow best practices to ensure that only authorized requesters obtain certificates signed by it.
- Do share certificates (only the certificate itself), these are meant to be public, and you do not gain any security value keeping these private.