Get SSH server key fingerprint

You could do this by combining ssh-keyscan and ssh-keygen:

$ file=$(mktemp)
$ ssh-keyscan host > $file 2> /dev/null
$ ssh-keygen -l -f $file
521 de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef host (ECDSA)
4096 8b:ad:f0:0d:8b:ad:f0:0d:8b:ad:f0:0d:8b:ad:f0:0d host (RSA)
$ rm $file

(unfortunately the much simpler ssh-keyscan host | ssh-keygen -l -f /dev/stdin does not work)


I recently had to do this myself so I thought I’d add an answer which shows how this can be done (with versions of OpenSSH 7.2 or newer) in one line using process substitution:

ssh-keygen -lf <(ssh-keyscan hostname 2>/dev/null)

The following text explains how these commands work and highlights some of the differences in behaviour between older and newer versions of the OpenSSH utilities.

Fetch public host keys

The ssh-keyscan command was developed so that users can obtain public host keys without needing to authenticate to the SSH server. From its man page:

ssh-keyscan is a utility for gathering the public ssh host keys of a number of hosts. It was designed to aid in building and verifying ssh_known_hosts files.

Key type

The type of key to be fetched is specified using the -t option.

  • rsa1 (obsolete SSH Protocol version 1)
  • rsa
  • dsa
  • ecdsa (recent versions of OpenSSH)
  • ed25519 (recent versions of OpenSSH)

In modern OpenSSH releases, the default key types to be fetched are rsa (since version 5.1), ecdsa (since version 6.0), and ed25519 (since version 6.7).

With older versions of ssh-keyscan (before OpenSSH version 5.1), the default key type was the out-dated rsa1 (SSH Protocol 1) so the key types would need to be explicitly specified:

ssh-keyscan -t rsa,dsa hostname

Get fingerprint hashes of Base64 keys

ssh-keyscan prints the host key of the SSH server in Base64-encoded format. To convert this to a fingerprint hash, the ssh-keygen utility can be used with its -l option to print the fingerprint of the specified public key.

If using Bash, Zsh (or the Korn shell), process substitution can be used for a handy one-liner:

ssh-keygen -lf <(ssh-keyscan hostname 2>/dev/null)

Note: With versions of OpenSSH before 7.2, the functions used by ssh-keygen to read files, did not handle named pipes (FIFOs) very well so this method wouldn’t work, thus requiring the use of temporary files.

Hashing algorithms

Recent versions of ssh-keygen print SHA256 fingerprint hashes of the keys. To get MD5 hashes of the server key fingerprints (the old behaviour), the -E option can be used to specify the hash algorithm:

ssh-keygen -E md5 -lf <(ssh-keyscan hostname 2>/dev/null)

Using a pipeline

If using a POSIX shell (such as dash) which doesn’t feature process substitution, the other solutions using temporary files will work. However, with newer versions of OpenSSH (since 7.2), a simple pipeline can be used since ssh-keygen will accept - as a filename for the standard input stream, allowing a one-line pipeline command.

ssh-keyscan hostname 2>/dev/null | ssh-keygen -E md5 -lf -

nmap provides this ability by using the ssh-hostkey script.

To return the key's hexadecimal fingerprint:

$ nmap [SERVER] --script ssh-hostkey

To return the key's content:

$ nmap [SERVER] --script ssh-hostkey --script-args ssh_hostkey=full

To return the key's visual bubble

$ nmap [SERVER] --script ssh-hostkey --script-args ssh_hostkey='visual bubble'

To return all of the above:

$ nmap [SERVER] --script ssh-hostkey --script-args ssh_hostkey=all

Source: nmap docs

Tags:

Ssh