Friday, March 10, 2017

Check a Certificate Key Identifier

On certificates as part of the signing process you submit a CSR (certificate signing request) to a CA (certificate authority) to be signed, but because of certificate expiration being a core concept in PKI those CAs will too expire. Or in the case of the SHA-1 deprecation you might be in a situation where you have a private key with a refreshed certificate associated with it, or in the case of a secure token or smart card you may have a single key but multiple certificates associated with it. This leads to the concept of Key Identifiers, which are encoded in certificates:

Here's an example of what a certificate would look like:
echo "Q" | openssl s_client -connect google.com:443 2>1 | openssl x509 -text -noout | grep -A1 'Key Identifier'
            X509v3 Subject Key Identifier:
                EB:27:08:F6:93:E5:92:F2:DE:06:FD:1F:9A:89:9F:F6:E4:97:51:30
--
            X509v3 Authority Key Identifier:
                keyid:4A:DD:06:16:1B:BC:F6:68:B5:76:F5:81:B6:BB:62:1A:BA:5A:81:2F
Breaking down this command:
  1. echo "Q" - send the 'Q' command to close down the connection as described in man s_client.
  2. openssl s_client -connect google.com:443 2>1 - connect to host and port combination google.com via port 443, additionally pipe stderr to stdout so it gets filtered out of the final output.
  3. openssl x509 -text -noout - The openssl s_client command emits the certificate information to stdout, and we can use a pipe to forward that to openssl x509 to read from stdin. We then ask to interpret the certificate and then provide the decoded output with -text and not emit the actual certificate again with -noout.
  4. grep -A1 'Key Identifier' - just grab the x509v3 section and the line after which is where the value is displayed.

In RFC 5280 § 4.2.1.1 it is indicated that this provides a signature of the private key used to sign the certificate. And in RFC 5280 § 4.2.1.2 it describes the strategy on how theses keys could be generated. The caveat here is that like the last section mentions you can do anything you want here to generate that value.

To then check what the signature of a key would be if you only have the private key and you are working with certificates signed by openssl, the fastest way is to self sign a certificate. You can do that as follows:
openssl req -new -x509 -key CA.key -sha256 -subj '/CN=test'| openssl x509 -text -noout | grep -A2 'Key Identifier'
            X509v3 Subject Key Identifier:
                B3:1B:00:4C:10:55:73:D9:91:66:36:1C:4B:4F:07:98:74:68:DE:09
            X509v3 Authority Key Identifier:
                keyid:B3:1B:00:4C:10:55:73:D9:91:66:36:1C:4B:4F:07:98:74:68:DE:09
By using this you now can do a direct comparison, and then look at an openssl x509 output to investigate who signed this certificate based on what you now know.