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/id_rsa.pub | 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 done
I've never seen an ed25519 key in the wild. It looks like this:
$ cat ~/ssh/ed25519-key.pub 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.
Tags: git, ssh 4 comments
If you use Go, you could use https://godoc.org/golang.org/x/crypto/ssh, marshal the key and hash it with SHA256.