Search code examples
sslopensslcertificatepuppetcsr

Fingerprint of certificate request (CSR)


I've a certificate request (see bottom) of which I'd like get fingerprint preferably from command-line (Unix). If my goal was only to verify integrity of a PEM file on two machines I could just use e.g. sha256sum csr.pem value but I'd like to get the same fingerprint as Puppet does:

puppet:~# puppetserver ca list --all
Requested Certificates:
    testbox   (SHA256)  7C:8C:A2:2C:17:42:C1:B9:55:A0:1D:EE:0D:C1:B0:65:B0:B4:AF:83:68:77:A8:0D:C4:6C:B1:41:25:FF:E7:C2

This fingerprint value is printed on both testbox and puppet machines when bootstrapping testbox and only thing they both share is the CA certificate (private key of which is stored on puppet). So the algorithm shouldn't require any private keys on input.

I assume the algorithm is standard, but I don't know cryptographic formats and openssl enough to figure out how to get it, and I'd specifically like to use openssl or some other widely available command line utility (i.e. not Ruby).

One of my failed attempts:

testbox:~# openssl x509 -fingerprint -in /etc/puppetlabs/puppet/ssl/certificate_requests/testbox.pem 
unable to load certificate
139644407518336:error:0909006C:PEM routines:get_name:no start line:../crypto/pem/pem_lib.c:745:Expecting: TRUSTED CERTIFICATE

Here's the actual certificate request:

testbox:~# cat /etc/puppetlabs/puppet/ssl/certificate_requests/testbox.pem 
-----BEGIN CERTIFICATE REQUEST-----
MIIEVzCCAj8CAQAwEjEQMA4GA1UEAwwHdGVzdGJveDCCAiIwDQYJKoZIhvcNAQEB
BQADggIPADCCAgoCggIBAKAT6FPs6RkT30lnNk0wpfhLtjrrAr/YdyDCUVTjV5jL
23iuLLSHes7yog/gACitGqCOnSz7J95OUtfGV+ACV8AEcyNpQazOqHhcLh15CYa7
8fDyVsoLzHWUKDMXhNllYrJFOoEDU/IP/y5hdS6e56pPZCVwYRxg9pjtvOX/FyUA
vXFA94IvqAgR2HdD7Vbr11mSmVNJuP9bWimhizvpzG4g3Xacvz7BhEZC5v/tIuH6
zaQtKCoBoxTFQhlFhY1F0iIMIjbTFTUuzPjCh5pMhXMxm0rgpH0SkvJp8bzesCGX
34JIDCOo6R197IttvbPh+6J91nMReOrYl4WAIMFHMz9L2dEClKbT0qWKjTHSUB6E
Pkia6d/gQzM4UcfP2NGAPnaWv3HZJPy6LnOHFoaxkfiMVGMlKISqF8cbkhGEneX0
V3Q8z60BAdr1q2i2rmPQkhp0MLwCoOzEcH13I43GhZuF/V6YbBcLt0UcEI0DC+VR
vP1sIFXj/BzQkITgzE9q067vRtgYVb85CtfESvSbLdci8noPz076wuaiRme8qzHM
SovvAcq6QGPKaB7K7veKAUW7riOaXHRzR6WAxE2t4WlZDmT/9liLPlxT38Mbl2LE
mVRPNvb1IUyWY5SoE4Dl/9ZNMlIReMrT/XVD/Udt5zOlKxica2wSHPIRyBDm5ah9
AgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAgEAAkqLZQQGf8cHPqX+MWmMu42sHETv
CSqRvKM1oLcli4OCPF15axLNUAXg7+wSPOLfUkznkqukSs+ZZKoKex232ZesrDRn
IG1kkVrYRWAO6kgHHTnQJx0HOawny1OObfIlkbq/PSiprlPK5OfjyTgjK4oIDqIy
50Vifqv2akgW4/HirgUe54dILuXRlntFJtDXyanMHcRhg/Vy+I7hfIbimuBoIWuF
Z/ULNcj25+/m0VjAYNJ4gkV/TgIcWhmRLvq7AFeFo3tmEsmrbnXJnBnt1RCpAOY4
CF3T5etAsG+6JfQ/erY3Kh6sGK5XOvLSQ6SautW8DzSGCV8XKv9jQYlbM/4c3HwX
4vzIxYueW+u2MlfJZcYfkr8RK9bmk4mJCa63AK3VgRtQK21IJqNOR9lgiP202b+T
9o8CmT+rxAnEZHIr9j2nDjPlaR63lAWpSKsS/HxXr6wh2JS/34+YuhbvZlSrxYoR
D8Ta3fZYkIX7aCEziSNqRgZgz+VGroxrQCjdvTYRzr2G6LUVrr0D4dUJnBt1DhZO
klV+pv2tFl5q9szTuu0dkLNyPYFOTjCTD3GxpsuMwmONMAzsMUT+ouLVoklmXxim
Ah3ZrRv4O/hnjRZM0+tV498b4G8ZZmyp80K1CTQwLJNewpk9n2I2K7RVGFtyXa9M
irfOVbUQKaBTrqg=
-----END CERTIFICATE REQUEST-----

Solution

  • If my goal was only to verify integrity of a PEM file on two machines I could just use e.g. sha256sum csr.pem value but I'd like to get the same fingerprint as Puppet does

    The general notion of the fingerprint/thumbprint of a certificate is a digest of the DER-encoded (binary) representation of the certificate. You can do this with the openssl x509 command directly... or indirectly:

    $ openssl x509 -in test.cer -noout -sha256 -fingerprint
    SHA256 Fingerprint=3E:A9:CB:54:36:DB:CF:23:50:D1:6B:D8:06:25:DC:0E:37:23:3E:A7:50:A5:D1:F3:05:0F:26:33:4E:F8:66:7C
    
    $ openssl x509 -in test.cer -outform der | sha256sum
    3ea9cb5436dbcf2350d16bd80625dc0e37233ea750a5d1f3050f26334ef8667c  -
    

    So the algorithm shouldn't require any private keys on input.

    That is correct.

    One of my failed attempts:

    testbox:~# openssl x509 -fingerprint -in /etc/puppetlabs/puppet/ssl/certificate_requests/testbox.pem 
    

    Because the fingerprint/thumbprint is the digest of the signed certificate, it cannot be determined from the request. (The certificate has its validity information, the CA identifier, and the CA's signature... and probably extensions not present in the request.)


    If you're trying to match a certificate to a certificate request, the only thing they're really guaranteed to have in common is the public key. If the -pubkey outputs match they're the same.

    $ openssl req -in test.csr -pubkey -noout
    -----BEGIN PUBLIC KEY-----
    MIIBJDANBgkqhkiG9w0BAQEFAAOCAREAMIIBDAKCAQEAr4HBy9ggP2JKU57WYIF1
    NyOTooN9SJDkihne02lzEVYglo1r4NPao4qnd74C7gtrk7ck6NzBK2MrT6gLvJJb
    zmJPTKfMYGMGs5QD4oyTLSTdVG/+TvajfxB3CyIV6oy7W/Qn6MTYm3nrM4N1EAxf
    g+Vd6bRGbd++7kJTmu8z7xh7d2DDsaGyEDwtgURWSgwQOaCchc9rWXTrUW/I1mI8
    lK46WguztMeSlX1DI5FWbPPipSr7DBQrngaBuJcmca8rgt05Cjm5Oc9xlWhofkmQ
    pjBQyndo3NazeIQvGP2x9tn/CWuve+uY3Pkw1m/P1QP1jUG/9GIS4k46/EXqQr2I
    RwIFAgAABEE=
    -----END PUBLIC KEY-----
    
    $ openssl x509 -in test.cer -pubkey -noout
    -----BEGIN PUBLIC KEY-----
    MIIBJDANBgkqhkiG9w0BAQEFAAOCAREAMIIBDAKCAQEAr4HBy9ggP2JKU57WYIF1
    NyOTooN9SJDkihne02lzEVYglo1r4NPao4qnd74C7gtrk7ck6NzBK2MrT6gLvJJb
    zmJPTKfMYGMGs5QD4oyTLSTdVG/+TvajfxB3CyIV6oy7W/Qn6MTYm3nrM4N1EAxf
    g+Vd6bRGbd++7kJTmu8z7xh7d2DDsaGyEDwtgURWSgwQOaCchc9rWXTrUW/I1mI8
    lK46WguztMeSlX1DI5FWbPPipSr7DBQrngaBuJcmca8rgt05Cjm5Oc9xlWhofkmQ
    pjBQyndo3NazeIQvGP2x9tn/CWuve+uY3Pkw1m/P1QP1jUG/9GIS4k46/EXqQr2I
    RwIFAgAABEE=
    -----END PUBLIC KEY-----
    

    While I don't have an example offhand, just because they don't match doesn't mean they're different. This is because some algorithms, such as RSA, there are multiple different legal encodings for the key in SubjectPublicKeyInfo and the CA could re-normalize when signing the certificate.

    For RSA you could open it with the openssl rsa command and then let OpenSSL re-normalize it (when writing it back out it won't remember which of the two representations were used)

    $ openssl req -in test.csr -pubkey -noout | openssl rsa -pubin -outform der | sha256sum
    writing RSA key
    3305c9f5c37cb13c152d087eea65ce1af3f0f846b309cb0426f1f42ae5fcbae0  -
    
    $ openssl x509 -in test.cer -pubkey -noout | openssl rsa -pubin -outform der | sha256sum
    writing RSA key
    3305c9f5c37cb13c152d087eea65ce1af3f0f846b309cb0426f1f42ae5fcbae0  -