Introduction
I got an interesting question about X.509 certificate thumbprints today from a colleague. Specifically, he wanted to know if you could renew a certificate and keep the thumbprint. The answer is no, unfortunately. So I thought I would explain why you can’t.
Certificate storage
The X.509 standard was first issued in 1988 and is described in several RFCs. It specifies, among other things, public key certificates, what we commonly refer to as X.509 certificates. X.509 certificates, in turn, currently come in three versions, v1, v2 and v3. The v3 certificates are described in RFC 5280. For the remainder of this post the terms certificate, public key certificate and X.509 certificate are used interchangeably.
X.509 certificates, as well as many other things in the X.509 standard, are described using Abstract Syntax Notation One (ASN.1). ASN.1 is a standard used to exchange information between systems independently of the systems’ encoding techniques. ASN.1 have several encoding rules:
- Basic Encoding Rules (BER)
- Canonical Encoding Rules (CER)
- Distinguished Encoding Rules (DER)
- XML Encoding Rules (XER)
- Canonical XML Encoding Rules (CXER)
- Extended XML Encoding Rules (E-XER)
- Packed Encoding Rules (PER, unaligned: UPER, canonical: CPER)
- Generic String Encoding Rules (GSER)
The original rules laid out for the ASN.1 standard were Basic Encoding Rules (BER), and CER and DER are more strict variants of BER. Digital certificates are usually stored in the file system as raw binary data, so DER (binary) is the most common. Certificates stored as raw binary usually have a .cer extension, but .der is also in use. Often the binary data is converted to Base64 ASCII files. This is called Privacy Enhanced Email (PEM), and these files commonly have one of these extensions: .pem, .crt, .cer, and .key.
Here is a screenshot of a DER encoded certificate opened in a HEX editor:
Here is the same cert encoded as Base64 also opened in a HEX editor:
Finally here is the same certificate in ASN.1 human readable form (this isn’t the whole cert):
So what does all this mean?
The RFC 5280 X.509 certificate definition
In RFC 5280 the basic syntax of a certificate (using ASN.1) defines three required fields:
Field | Definition from RFC 5280 |
tbsCertificate | The sequence TBSCertificate contains information associated with the subject of the certificate and the CA that issued it. Every TBSCertificate contains the names of the subject and issuer, a public key associated with the subject, a validity period, a version number, and a serial number; some MAY contain optional unique identifier fields. |
signatureAlgorithm | The signatureAlgorithm field contains the identifier for the cryptographic algorithm used by the CA to sign this certificate. |
signatureValue | The signatureValue field contains a digital signature computed upon the ASN.1 DER encoded tbsCertificate. The ASN.1 DER encoded tbsCertificate is used as the input to the signature function. This signature value is encoded as a BIT STRING and included in the signature field. |
The tbsCertificate field is by far the largest containing also any extensions the certificate may have like key usage, alternate names etc. RFC 5280 lists all the possible extensions. signatureAlgorithm contains only one piece of data; the hashing algorithm used by the signing authority to sign this particular certificate. signatureValue contains the signature itself, calculated with the hashing algorithm from signatureAlgorithm.
The signature
To produce the certificate signature the signing authority takes the tbsCertificate field in ANS.1 DER encoded form (binary data) and applies the hashing algorithm to it. Inside the tbsCertificate field are some important fields. Specifically the subject name (CN), the hashing algorithm the signing authority used to sign the certificate and the subject’s public key. By signing all these fields the signing authority certifies that the subject in question does in fact own the public key in the certificate. It is a requirement that the signature field within the tbsCertificate field match the signatureAlgorithm field in the certificate. The important distinction here is that it is only the signature field inside the tbsCertificate field that is included in the signature, not the signatureAlgorithm field.
The Windows Cryptographic API
When a certain implementation uses the certificate it calculates and resolves a lot of information not included in the certificate itself. These are things like hash values of various fields and OIDs used to describe e.g. signing algorithms. Certificate Revocation checking is also usually performed and chaining and validation. One example of this behavior is the Windows CryptoAPI Cryptographic Shell Handler. This is the component that shows you a picture like the one below when you double click a certificate from Windows Explorer.
Legend
Actual fields in the certificate | |
Extensions in the certificate | |
Computed fields not actually part of the certificate data |
The certutuil.exe command line utility goes into even greater detail if you inspect (dump) a certificate:
X509 Certificate:
Version: 3
Serial Number: 6e9235460edbb5944d59f9f1a8f1cfe6
Signature Algorithm:
Algorithm ObjectId: 1.3.14.3.2.29 sha1RSA (shaRSA)
Algorithm Parameters:
05 00
Issuer:
CN=Morgan Simonsen
Name Hash(sha1): 935093f16909002acd98626df485fa22b41d9dfd
Name Hash(md5): c32bdd1ad8eaf126fd96b2f7f23f2b9f
NotBefore: 16.04.2013 10:57
NotAfter: 01.01.2040 01:59
Subject:
CN=Morgan Simonsen
Name Hash(sha1): 935093f16909002acd98626df485fa22b41d9dfd
Name Hash(md5): c32bdd1ad8eaf126fd96b2f7f23f2b9f
Public Key Algorithm:
Algorithm ObjectId: 1.2.840.113549.1.1.1 RSA (RSA_SIGN)
Algorithm Parameters:
05 00
Public Key Length: 2048 bits
Public Key: UnusedBits = 0
0000 30 82 01 0a 02 82 01 01 00 ac ed c3 1d 11 7f 63
0010 db 25 50 2e 9a c6 c1 f5 b7 23 c8 a0 71 a4 6e d6
0020 c8 29 17 8f 76 b6 8c 88 33 bf c9 0e 3d c8 0d 87
0030 11 60 e4 f0 77 ae e5 b4 47 6f b1 35 98 d3 44 d0
0040 52 c7 60 2e 7f e9 6c 3c 61 c2 36 3d a7 f5 32 88
0050 de 3c c4 79 62 91 b0 4b 24 78 a2 2e 6a 29 a9 ee
0060 0e 7a d8 0d 9e 12 7b b2 53 d1 17 8c 01 dc eb fb
0070 18 4d c0 ae df 61 7e 2b dd 15 b5 65 b3 bc b9 25
0080 58 c9 ed 9e ef 9f 26 9b 79 c3 8e 13 92 9e 62 f3
0090 fe 8d ab 33 b4 40 a1 7b 0e b1 71 56 b4 9d 7b cb
00a0 61 9d 70 1d 9d b4 49 c9 46 42 fc 64 44 67 eb 8b
00b0 ea 7c 29 31 cb 4c 32 12 91 6c dd 04 59 07 51 6a
00c0 e6 40 fa ea 4e b2 ae 64 21 2e 6b 00 99 f0 7c 26
00d0 6e ad 6c 15 18 36 dc 81 61 e9 ce 28 7f f8 89 82
00e0 ee ed c5 ee 54 ee aa cd 01 72 75 71 59 fd fc cd
00f0 4d 53 3e 22 71 47 7f 24 e5 51 28 36 12 09 6b 0d
0100 af c9 37 9b e0 d1 00 67 11 02 03 01 00 01
Certificate Extensions: 1
2.5.29.1: Flags = 0, Length = 44
Authority Key Identifier
KeyID=b4 44 ec b5 97 5f 54 f8 ee e8 7b d0 1e c9 81 92
Certificate Issuer:
CN=Morgan Simonsen
Certificate SerialNumber=6e 92 35 46 0e db b5 94 4d 59 f9 f1 a8 f1 cf e6
Signature Algorithm:
Algorithm ObjectId: 1.3.14.3.2.29 sha1RSA (shaRSA)
Algorithm Parameters:
05 00
Signature: UnusedBits=0
0000 8b 55 a5 5f f2 b3 2d 19 36 e9 9c cc 92 16 4e 62
0010 18 19 19 3e 7d 76 93 dd 04 9b 5e 0e b7 80 d7 38
0020 9d 1f b9 18 c3 6c 28 be d6 64 a3 be 04 60 fc 63
0030 6d 26 dc 68 2b 3d c0 88 6d 36 22 a7 e7 c4 15 dc
0040 2b af 18 61 10 bb 3b 32 78 a6 36 08 81 29 b5 6a
0050 3e a2 2d c7 d0 31 69 1f f3 fc 67 b7 df 2d e0 4e
0060 5d 37 ab a4 d1 56 e2 96 55 d7 21 d2 68 74 dc 5f
0070 b2 e5 12 54 e2 34 ae a0 08 9e 26 2f e2 4e 4e 98
0080 86 f7 6e ac ef e0 43 1e 0b 9d 59 3d a3 3d 55 03
0090 11 7c f1 df 00 1d 47 35 43 32 91 2a dc 4d 4b 9e
00a0 22 bf a1 f5 1e 1d ad d0 ee 73 34 99 43 82 5d 9e
00b0 b6 aa db 93 25 77 42 0a bd d2 b2 9a e9 0e 31 2d
00c0 63 4c 4a 37 51 b4 b6 81 47 a8 94 fd e7 43 82 f7
00d0 ee 66 f1 d0 00 ff cf 9f b0 a6 40 08 05 b8 ff 94
00e0 0b cd cf 50 e3 73 6a 03 2f 6f 95 8e 1b 51 e7 a7
00f0 ac ff 39 84 8c bf b8 65 41 c9 82 38 93 7c cb ab
Signature matches Public Key
Root Certificate: Subject matches Issuer
Key Id Hash(rfc-sha1): 91 cb 09 47 49 10 66 f1 fb 5b bc 8b 5e 0b b1 43 2c d8 80 b2
Key Id Hash(sha1): 4a eb 50 03 a3 78 80 bd 20 a0 00 da c6 f9 ef 8d cc 07 98 52
Key Id Hash(md5): 6a993e53bd40f8f69483d6da66f22a8f
Key Id Hash(sha256): 6979da8247c3080de96e861e9f000a22d6120170a3982bea4e9f054598f6453f
Cert Hash(md5): 94 08 89 bf 34 7e 17 2f 46 d6 25 49 f8 80 1f 6b
Cert Hash(sha1): 0b 61 2f 71 4b 8d ef d5 59 2b d4 5d a9 fe 8c c5 bb ba 36 48
Cert Hash(sha256): 52c93aa9bd509f8b375e0ec8340d9219bac4386497b521d8a7b800eda22e850c
Signature Hash: dee3cb948ffb745c3047e4f393bcf9144863b733
CertUtil: -dump command completed successfully.
The Thumbprint
As you can see from the output of the Crypto Shell Extension and Certutil.exe the thumbprint is a computed field, i.e. not a part of the certificate data itself. In the GUI these are called Properties. In the shell extension the thumbprint is called thumbprint and in the Certutil output it is called Cert hash. From this we can surmise that the thumbprint is some kind of hash or one way function (OWF), whose friendly name is thumbprint. (The fact that the shell extension actually has a field called Thumbprint algorithm also helps.) Certutil is also kind enough to compute both a SHA1 and an MD5 hash for us, while the GUI will only do SHA1. As far as I can tell Windows always uses SHA1 to calculate the thumbprint hash, regardless of which signature algorithm is used in the certificate itself.
So what is the thumbprint a hash of? Turns out it is actually the whole certificate, i.e. the binary data representing the three required fields (tbsCertificate, signatureAlgorithm and signature). You can verify this by using a tool that can generate hashes directly from the certificate binary DER file in the file system. In the screenshot below I have used the HashCheck Shell Extension. This tool has a nice feature where you can paste a hash you have obtained from somewhere and see if it matches any of the computed hashes for the file. Here I have copied the thumbprint hash value from Certutil and pasted into the tool:
Since the thumbprint is a hash of the certificate in binary DER encoding this will not work if your certificate is stored in any other format than DER.
Conclusion
So now we have the answer to why you cannot request a new certificate, or renew an existing one, with the same thumbprint. Changing anything in the certificate data will produce a completely different hash result and thus a completely different thumbprint.
The thumbprints purpose is actually to make it easy to locate a particular certificate in the certificate store of a system. Let’s say you have a webserver that needs a certificate. Instead of specifying a certificate by subject name, validity or anything else you just supply the thumbprint to the webserver.
More information
To write this post I created a self signed certificate with my name as the subject. The command I used was this:
makecert.exe -pe -n “CN=Morgan Simonsen” -ss My -r morgan_simonsen.der
You can download all the various versions of the certificate from this post from the following link if you want to look in more detail and compare with what I have written.
There are four files in the archive:
File | Format |
morgan_simonsen.der | Binary DER format |
morgan_simonsen.crt | PEM (Base64) format |
morgan_simonsen.asn | Raw ASN.1 ASCII data |
morgan_simonsen.txt | Certutil –dump –asn of the DER cert |
Hello Morgan;
Do you have a list with all the changes that affect the certificate thumbprint, or lead to generation of a new local machine certificate?
As you may know the local machine certificate for windows 2008 server is stored at OS registry under the key: HKEY_LOCAL_MACHINESOFTWAREMicrosoftSystemCertificatesRemote DesktopCertificates on a BLOB.
I know with you change something in the windows (OS), like computer name, IP address, the certificate will change too.
I would like to know the complete list of these changes.
Regards;
Great detailed article!
An updated way to obtain a selfsigned certificate is to use PowerShell (this saves you from downloading the big Windows SDK just for the small makefile.exe program):
$selfsignedcert = New-SelfSignedCertificate -KeyExportPolicy Exportable -Subject “CN=Tom Aafloen” -CertStoreLocation “Cert:\CurrentUser\My”
Export-Certificate -Cert $selfsignedcert -FilePath .\TomAafloen-SelfSigned.cer