Generating fingerprints from SSH keys

Wednesday, 7 October 2015

I've been allowing users to upload SSH public-keys, and displaying them online in a form. Displaying an SSH public key is a pain, because they're typically long. That means you need to wrap them, or truncate them, or you introduce a horizontal scroll-bar.

So rather than displaying them I figured I'd generate a fingerprint when the key was uploaded and show that instead - This is exactly how github shows your ssh-keys.

Annoyingly there is only one reasonable way to get a fingerprint from a key:

  • Write it to a temporary file.
  • Run "ssh-keygen -lf temporary/file/name".

You can sometimes calculate the key via more direct, but less obvious methods:

awk '{print $2}' ~/.ssh/ | base64 -d | md5sum

But that won't work for all key-types.

It is interesting to look at the various key-types which are available these days:

mkdir ~/ssh/
cd ~/ssh/
for i in dsa ecdsa ed25519 rsa rsa1 ; do
  ssh-keygen -P "" -t $i -f ${i}-key

I've never seen an ed25519 key in the wild. It looks like this:

$ cat ~/ssh/
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMcT04t6UpewqQHWI4gfyBpP/ueSjbcGEze22vdlq0mW skx@shelob

Similarly curve-based keys are short too, but not as short:

ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLTJ5+  \
 rWoq5cNcjXdhzRiEK3Yq6tFSYr4DBsqkRI0ZqJdb+7RxbhJYUOq5jsBlHUzktYhOahEDlc9Lezz3ZUqXg= skx@shelob

Remember what I said about wrapping? Ha!

Anyway for the moment I've hacked up a simple perl module SSH::Key::Fingerprint which will accept a public key and return the fingerprint, as well as validating the key is well-formed and of a known-type. I might make it public in the future, but I think the name is all wrong.

The only code I could easily find to do a similar job is this node.js package, but it doesn't work on all key-types. Shame.

And that concludes this weeks super-happy fun-time TODO-list item.



Comments On This Entry

[gravitar] Philipp Kern

Submitted at 10:39:39 on 7 october 2015

If you use Go, you could use, marshal the key and hash it with SHA256.

[author] Steve Kemp

Submitted at 10:56:04 on 7 october 2015

Thanks for the tip. I sometimes use Go, but this particular project is perl-based.

[gravitar] Matthew Walster

Submitted at 17:14:03 on 8 october 2015

Why not just pipe it into ssh-keygen instead then?

$ ssh-keygen -l -f /dev/stdin <<<"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFkJ+hQjkgwcK/HVoct871jAi1Z5LsZaAfOOepj9CsJ1 dotwaffle@engelbert" 256 SHA256:NypbzriJTz9K1S7R4XmHRb8cWSH5xu+LLMubZdGHpf8 dotwaffle@engelbert (ED25519)

[author] Steve Kemp

Submitted at 18:08:10 on 8 october 2015

My objection wasn't that you needed to write to a file, but that you needed to exec a binary.

But I think that your use of /dev/stdin won't work. Certainly for me it fails:

$ cat ~/.ssh/ | ssh-keygen -l -f /dev/stdin
/dev/stdin is not a public key file.


Comments are closed on posts which are more than ten days old.

Recent Posts

Recent Tags