SSH Pubilc Key Fingerprints
Published 2018-12-4In yesterday's article, The SSH Public Key format, I gave a simple breakdown of the SSH Public key format.
Today's goal is to re-create the a public key fingerprint (RFC 4716).
I've done this myself with ssh-fingerprint.js and you can see it live in action with this nifty online demo:
SSH Public Key Format
The important part that we need to readdress is that a key looks like this:
id_rsa.pub
:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCba21UHE+VbDTpmYYFZUOV+OQ8AngOCdjROsPC0KiEfMvEaEM3NQl58u6QL7G7QsErKViiNPm9OTFo6HF5JijfWzK7haHFuRMEsgI4VwIYyhvqlJDfw/wt0AiVvSmoMfEQn1p1aiaO4V/RJSE3Vw/uz2bxiT22uSkSqOyShyfYE6dMHnuoBkzr4jvSifT+INmbv6Nyo4+AAMCZtYeHLrsFeSTjLL9jMPjI4ZkVdlw2n3Xn9NbltF3/8Ao8dQfElqw+LIQWqU0oFHYNIP4ttfl5ObMKHaKSvBMyNruZR0El/ZsrcHLkAHRCLj07KRQJ81l5CUTPtQ02P1Eamz/nT4I3 root@localhost
It's it's got three obvious parts:
- type name (i.e.
ssh-rsa
) - base64-encoded ssh public key (i.e.
AAAAB3Nz...nT4I3
) - optional comment (i.e.
root@localhost
)
Fingerprinting
The data we need for fingerprinting is the entire2nd section. It's the base64-encoded public key in the special SSH format.
The fingerprint is simply the sha256 sum of the whole blob, essentialy this:
'SHA256:' + base64-encode( sha256( base64-decode( encoded-ssh-pubklic-key ) ) )
Or, if you prefer to break it down into two steps:
key-blob = base64-decode( pub.split(' ')[1] )
'SHA256:' + base64-encode( sha256( key-blob ) )
The end result looks like this:
SHA256:yCB62vBVsOwqksgYwy/WDbaMF2PhPijAwcrlzmrxfko
Note: The trailing =
are stripped off. If that weren't the case you would see
SHA256:yCB62vBVsOwqksgYwy/WDbaMF2PhPijAwcrlzmrxfko=
, which is incorrect.
Older versions of ssh used MD5 for the fingerprint and would output the value in hex, like this:
ea:b2:71:65:c0:5d:be:15:eb:bb:45:ad:b9:86:d4:ec
We don't use md5 anymore because... reasons.
(you can google to learn about it, but the topic is so old now that I'm not going to bother with it)
Anyway, the switch to base64 kept the printable character width about the same even though the new hash is much longer.
Output formats
When you run ssh-keygen
you'll get the abbreviated fingerprint, which still
includes the comment of the key.
The key fingerprint is:
SHA256:yCB62vBVsOwqksgYwy/WDbaMF2PhPijAwcrlzmrxfko root@localhost
But if you run ssh-keygen -lf ~/.ssh/id_rsa.pub
you'll actually get the key's
bit size and type as well:
2048 SHA256:yCB62vBVsOwqksgYwy/WDbaMF2PhPijAwcrlzmrxfko root@localhost (RSA)
If you specifically need to mimic the output formats of ssh-keygen
, you'll want
to go back and give The SSH Public Key format
a read as well. It explains how to break the blob into its various pieces. With EC keys you actually get
the size of the key in the type name, so this is really only important for RSA, although you could probably
make reasonable-enough guesses.
Demo Time
If you missed it before, here's the link to the online demo:
By AJ ONeal
Did I make your day?
Buy me a coffee
(you can learn about the bigger picture I'm working towards on my patreon page )