Getting SHA1 Digest of SSH Public Key

It seems like this should be easy. I run "ssh-keygen -l -f " (the default seems to be SHA1). All of the examples show it printing the hex-formatted digest with a little extra, harmless information. Yet, on my Mac I'm getting a useless, opaque string.

I should mention that the "-E" parameter works on Mac (10.10) but is unavailable in Ubuntu (14.04). Keep that in mind if it doesn't work for you.

$ ssh-keygen -l -E md5 -f dustin.pem
2048 MD5:29:ed:da:d3:5a:8c:78:4f:62:d3:fd:0c:77:5b:6d:d9 dustin.pem.pub (RSA)

$ ssh-keygen -l -E sha1 -f dustin.pem
2048 SHA1:x2ENPL+vzVdlgkIyu0tAhVQ+H4U dustin.pem.pub (RSA)

$ ssh-keygen -l -E sha256 -f dustin.pem
2048 SHA256:agJs/axI8QPzet/eoPMDxLSf37fd1bgsMX4Di0gqMy4 dustin.pem.pub (RSA)

Both of the attempted SHA algorithms return opaque, but different, ASCII strings.

What am I missing? How do I get a SHA1 hex-digest without having to copy my key to a Linux system to do it?

Thanks.


UPDATE: this answer is about OpenSSH fingerprints. Per comment from the OP the actual problem was apparently AWS fingerprints, which at the time I didn't know are different; for that see Why does my OpenSSH key fingerprint not match the AWS EC2 console keypair fingerprint? and https://stackoverflow.com/questions/19251562/importing-key-pair-into-amazon-aws-wrong-fingerprint and probably more.


Traditionally OpenSSH displayed (public) key fingerprints using MD5 in hex, or optionally as 'ASCII art' or 'bubblebabble' (a series of nonsense but pronounceable 5-letter quasiwords); 6.8 in March 2015 added options for SHA1 and SHA256 in (PEMstyle) base64, with the latter now the default, and in all three cases the hash name prefixed so you know which it is. ssh-keygen -l has -E option only since then, and Ubuntu 14.04 dates from before March 2015.

You should not need a SHA1 digest in hex for verifying a host, since ssh client never displays that, only MD5-hex or SHA1-base64 (not by default) or SHA256-base64. If you want one anyway, you can do it fairly easily except for an 'rsa1' key and you should have stopped using SSHv1 protocol and thus rsa1 keys before Barack Obama became US President.

Take the base64 'blob' from

  • field 2 of id_$alg.pub or similar file, or output of ssh-keygen -y
  • field 3 of line in known_hosts file unless it has a marker then field 4
  • field 2 of line in authorized_keys file unless it has options then field 3

and convert it from base64 to binary, hash that with the desired hash and display in the desired representation. Since openssl by default displays hashes in hex, and can convert from (and to) base64, you could do something like

awk '{print $2}' ~/.ssh/id_xxx.pub | openssl base64 -d -A | openssl sha1

Note the -A; otherwise openssl (depending on version) may silently fail to decode base64 longer than 76 characters -- and OpenSSH pubkey blobs except ed25519 are longer. (Thanx Bernhard Wagner for catching a bug -- and drawing my attention back to this old answer so I could add the scope fix above.)

Also note that you can tell a newer ssh client to display the old MD5-hex fingerprint with -o FingerprintHash=MD5 or an equivalent ssh_config setting.