285

I always find that I get this message when I ssh into a new machine:

12:f8:7e:78:61:b4:bf:e2:de:24:15:96:4e:d4:72:53

What does it stand for? Will every machine have the same fingerprint every time?

How are these fingerprints generated? What parameters do they depend on?

Oliver Salzburg
  • 86,445
  • 63
  • 260
  • 306
TheOneTeam
  • 5,107
  • 7
  • 36
  • 46

7 Answers7

295

You can generate a fingerprint for a public key using ssh-keygen like so:

ssh-keygen -lf /path/to/key.pub

Concrete example (if you use an RSA public key):

$ ssh-keygen -lf ~/.ssh/id_rsa.pub
2048 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff /Users/username/.ssh/id_rsa.pub (RSA)

The first part (2048) is the key length in bits, second part (00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff) is the fingerprint of the public key and the third part is location of the public key file itself.

In newer versions of OpenSSH, Base64 encoded SHA-256 is shown instead of hexadecimal MD5. To show the legacy style hash, use

$ ssh-keygen -l -E md5 -f ~/.ssh/id_rsa.pub
Franklin Yu
  • 716
  • 1
  • 7
  • 22
Benjamin Oakes
  • 4,613
  • 5
  • 23
  • 30
  • do u know how to translate into 12:f8:7e:78:61:b4:bf:e2:de:24:15:96:4e:d4:72:53 this format from that public key? – TheOneTeam Jul 24 '12 at 16:37
  • @KitHo I'm not sure if I understand your question. I updated the example, as I think `ssh-keygen -lf` will do what you want. – Benjamin Oakes Jul 24 '12 at 18:53
  • Supposing the two don't match, what's the next step to determine if you made a dumb mistake or if there is a man in the middle? – Michael Aug 05 '14 at 23:01
  • 10
    When SSH-ing into a new machine, what one sees is _not_ a user's pubkey fingerprint, but the host's pubkey fingerprint. So a better example for the question's context is `ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub`. It shows the fingerprint that is also shown on SSH logins to localhost. – tanius Aug 25 '14 at 00:26
  • 92
    My `ssh-keygen` reported `sha256` fingerprints. In order to get `md5` fingerprints I ran `ssh-keygen -l -E md5 -f ~/.ssh/id_rsa.pub`. #archlinux – Justin C Oct 28 '15 at 22:03
  • 12
    (@JustinC) OpenSSH versions 6.8 (March 2015) and up changed to SHA256, displayed in base64 rather than hex, by default. For the client use `ssh -o FingerprintHash=md5` or the equivalent in `ssh_config` and on things that use `ssh` like `scp`. – dave_thompson_085 Jun 12 '16 at 19:36
  • @dave_thompson_085 Thanks, that was what I was looking for. – Jonathan Cross Jun 21 '16 at 18:33
  • 3
    to get a visual representation (ASCII art) of the public key: `ssh-keygen -lvf ~/.ssh/id_rsa.pub` – math2001 Dec 04 '19 at 22:20
  • is this method `ssh-keygen -lf` still valid on an ssh certificate as well? – openCivilisation Jun 18 '21 at 13:10
122

The fingerprint is based on the host's public key, usually based on the /etc/ssh/ssh_host_rsa_key.pub file.  Generally it's for easy identification/verification of the host you are connecting to.

If the fingerprint changes, the machine you are connecting to has changed their public key. This may not be a bad thing (happens from re-installing ssh), but it could also indicate that you are connecting to a different machine at the same domain/IP (happens when you are connecting through something like a load balancer) or that you are being targeted with a man-in-the-middle attack, where the attacker is somehow intercepting/rerouting your ssh connection to connect to a different host which could be snooping your username/password.

Bottom line: if you get warned of a changed fingerprint, be cautious and double check that you're actually connecting to the correct host over a secure connection. Though most of the time this is harmless, it can be an indication of a potential issue.

See: http://www.lysium.de/blog/index.php?/archives/186-How-to-get-ssh-server-fingerprint-information.html
and: http://en.wikipedia.org/wiki/Public_key_fingerprint

madmaze
  • 4,186
  • 6
  • 34
  • 46
  • 18
    "...be cautious and double check that you're actually connecting to the correct host over a secure connection" -- stupid question, but how can you do this easily? – Savara Aug 10 '15 at 11:00
  • 15
    @Savara When you are connecting to an SSH server which you did not connect before, you should request the public key of the SSH server from the server admin. The server admin will give you a piece of text. You should append this text to the file `~/.ssh/known_hosts`. This way, when you connect to the server, your SSH client will recognize this server, since you have saved its public key to `known_hosts`. Hence, actually you should *never* say "yes" when the SSH client tells you "The authenticity of the host cannot be established". You should always add the public key of the server beforehand. – Utku Mar 24 '17 at 16:06
  • @Savara If you do this, you will know that something fishy is going on when your SSH client tells you "The authenticity of the client cannot be established" or when it tells you "The public key of the server has been changed". Hence, you should always add the public key of the server to your `~/.ssh/known_hosts` file beforehand and *never* say yes when your SSH client tells you "The authenticity of the client cannot be established" or when it tells you "The public key of the server has been changed". – Utku Mar 24 '17 at 16:09
  • 7
    Yeah, I'm fully aware of how the mechanics of viewing SSH fingerprints works, but a large percentage of the time you don't have the option to get the fingerprint through another channel. TOFU is sadly the best we often get. – Savara Mar 25 '17 at 17:55
  • Is there a way to check the authenticity even after answering "yes"? – exchange Mar 03 '18 at 11:27
  • Found this link where one can backcheck the fingerprint of github, maybe it helps? https://help.github.com/articles/github-s-ssh-key-fingerprints/ – exchange Mar 03 '18 at 12:17
  • @Utku but fingerprint is done via public key, and public key is not a secret info, so how passing public key fingerprint helps to avoid man in the middle attack ? what if that man in the middle also has the same public key and public key fingerprint ? – isxaker Jan 04 '23 at 17:02
  • @isxaker because the public key is used by the client to encrypt messages to the server, which needs the private key to decrypt them. the man in the middle would have to substitute their own public key, and therefore their own fingerprint, which assuming you've already seen the genuine fingerprint, you'd notice the substitution. – Phil May 05 '23 at 01:07
91

The fingerprint is the MD5 over the binary data within the Base64-encoded public key.

$ ssh-keygen -f foo
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in foo.
Your public key has been saved in foo.pub.
The key fingerprint is:
65:30:38:96:35:56:4f:64:64:e8:e3:a4:7d:59:3e:19 andrew@localhost
The key's randomart image is:
+--[ RSA 2048]----+
|       +*..+*    |
|      =. +.=     |
|     . . .o .    |
|         o+   E  |
|        S= . + o |
|        . o o +  |
|           .   . |
|                 |
|                 |
+-----------------+
$ cat foo.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEbKq5U57fhzQ3SBbs3NVmgY2ouYZfPhc6cXBNEFpRT3T100fnbkYw+EHi76nwsp+uGxk08kh4GG881DrgotptrJj2dJxXpWp/SFdVu5S9fFU6l6dCTC9IBYYCCV8PvXbBZ3oDZyyyJT7/vXSaUdbk3x9MeNlYrgItm2KY6MdHYEg8R994Sspn1sE4Ydey5DfG/WNWVrzFCI0sWI3yj4zuCcUXFz9sEG8fIYikD9rNuohiMenWjkj6oLTwZGVW2q4wRL0051XBkmfnPD/H6gqOML9MbZQ8D6/+az0yF9oD61SkifhBNBRRNaIab/Np7XD61siR8zNMG/vCKjFGICnp andrew@localhost
$ echo 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDEbKq5U57fhzQ3SBbs3NVmgY2ouYZfPhc6cXBNEFpRT3T100fnbkYw+EHi76nwsp+uGxk08kh4GG881DrgotptrJj2dJxXpWp/SFdVu5S9fFU6l6dCTC9IBYYCCV8PvXbBZ3oDZyyyJT7/vXSaUdbk3x9MeNlYrgItm2KY6MdHYEg8R994Sspn1sE4Ydey5DfG/WNWVrzFCI0sWI3yj4zuCcUXFz9sEG8fIYikD9rNuohiMenWjkj6oLTwZGVW2q4wRL0051XBkmfnPD/H6gqOML9MbZQ8D6/+az0yF9oD61SkifhBNBRRNaIab/Np7XD61siR8zNMG/vCKjFGICnp' \
    | base64 -D | md5
6530389635564f6464e8e3a47d593e19

The md5sum 6530389635564f6464e8e3a47d593e19 is the fingerprint displayed when the key is generated, only without the separating colons.


However, if you’re dealing with the fingerprints that Amazon shows in the EC2 Key Pairs console, unfortunately that may be a different beast. If it’s a 32-digit hex string, it’s the standard MD5 SSH public key fingerprint above. But if it’s 40 hex digits, it’s actually a fingerprint computed by taking the SHA1 of the private key in PKCS#8 format:

$ openssl pkcs8 -in foo -nocrypt -topk8 -outform DER | openssl sha1 -c
e2:77:39:d3:53:a7:62:68:5f:da:82:0e:99:61:30:64:a2:88:c4:58
Maarten Bodewes
  • 1,759
  • 2
  • 10
  • 19
andrew.n
  • 1,135
  • 8
  • 9
  • 1
    I found this answer helpful in the following scenario. Your system uses SHA1 to calculate the fingerprint, but your friend's uses md5. I shared a fingerprint which was SHA1 and it didn't match the MD5 her system generated. This helped - thank you! sed 's|^ssh-rsa ||' /etc/ssh/ssh_host_rsa_key.pub |sed 's|==.*$|==|' |base64 -d| md5sum – Liczyrzepa Jun 05 '15 at 19:25
  • This is highly relevant in understanding why this fingerprint will not match those in DNS SSHFP records, because they use SHA-1 or SHA-256 digests. – neirbowj Dec 30 '15 at 21:28
  • 1
    @Liczyrzepa the publickey field may or may not have '==' at the end depending on the key type and bitsize; safer and IMO easier to use `awk '{print $2}' /path/to/keyfile.pub` or similar. – dave_thompson_085 Jun 12 '16 at 19:41
  • 17
    This is the only answer that explains how the fingerprint is calculated – greuze Sep 29 '16 at 14:34
  • 2
    However in Linux Mint the command is: ```cat id_rsa.pub | cut -d' ' -f2 | base64 -d | md5sum``` – greuze Sep 29 '16 at 14:40
  • With `ssh-keygen -l` (id_rsa), I get `2048 SHA256:... ti@ti (rsa)`. Then I do `echo '..'| base64 -d|sha256sum` but I get another fingerprint. Strange – Timo Apr 11 '18 at 07:35
  • MD5 generates a 128 bit and hence 16 byte fingerprint and not a 32 byte long one. Probably you wanted to say "If it's a sequence of 32 hexadecimal digits" (see: MD5's [RFC 1321](https://www.ietf.org/rfc/rfc1321.txt)), same for sha1 (see: sha1's [RFC 3174](https://tools.ietf.org/html/rfc3174)) – Murmel Apr 12 '18 at 11:32
  • 2
    ssh, for a long time now, uses base64 encoded sha256 hashes. To calculate the sha256 fingerprint from the shell: `awk '{print $2}' ~/.ssh/id_ed25519.pub | base64 -d | sha256sum | xxd -r -p | base64 | tr -d =` – joshperry Jun 04 '19 at 18:05
  • 1
    thank you for providing this answer. It helped to answer, for me, where the fingerprint is actually coming from and how it is generated. – tisaconundrum Feb 10 '21 at 14:28
37

If you want to check an SSH key file to see if it is the same as what is reported as the "Deploy key" by github, this is for you...

From the private URL: https://github.com/<username>/<repo_name>/settings/keys you will see screenshot from github

At the terminal:

$ ls -l id*
-rw-------  1 bruno  staff  1675 Mar 29 17:03 id_rsa
-rw-r--r--  1 bruno  staff   416 Mar 29 17:03 id_rsa.pub

$ ssh-keygen -E md5 -lf id_rsa
2048 MD5:07:b4:00:a4:65:ef:44:89:05:84:60:0c:c9:b2:36:5e ec2-user@ip-10-2-1-16.ec2.internal (RSA)

$ ssh-keygen -E md5 -lf id_rsa.pub
2048 MD5:07:b4:00:a4:65:ef:44:89:05:84:60:0c:c9:b2:36:5e ec2-user@ip-10-2-1-16.ec2.internal (RSA)

You will notice that you get the same fingerprint for both the private and public keys.

That same command can be combined with a neat feature of GitHub, which is the fact that they publicly serve users' SSH public keys at https://github.com/<username>.keys

Here is a one-liner you can use to take advantage of it.

$ curl -sL https://github.com/RichardBronosky.keys | while read; do echo -e "\nkey #$((++i)):"; ssh-keygen -E md5 -lf - <<<"$REPLY"; echo $REPLY; done

key #1:
2048 MD5:07:b4:00:a4:65:ef:44:89:05:84:60:0c:c9:b2:36:5e no comment (RSA)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJGT35gvsFveu+80qgurrLHId0h55E9jliM7Fo0mV9b7eg3EfyagkAcJUSMFkoov3HY4CW0yzOc7WlN57ABwvpRz1ioFDex0n0FkjoSEs5ROeT1OneRK6Bf6XnplgPuQ/LSSkv3kmK6I29R+YWi6TjDvLLoA5BrXJjOMfUv36jxWCDtk/5ZdhMZqhsMuDm06Jg5JBu6n5jQaZkmaIaunz7vOfwVG9LoCI+MYyIdo2S4VTva7Ee7jfAvgSUUgHTjhzsPO0/Ww5a/Kz2ehXW27aJxj/QPLfYR2LmTMbQKm3WpB8P1LjoiU7zjPoVoZ43a4P2JLUDidGKCd3eY5b5xewz

key #2:
2048 MD5:f7:98:f1:0b:73:c6:2a:21:00:7a:70:1d:0f:cf:d8:cc no comment (RSA)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCQsZrjwKjB4WnE4SwVdDX5eEMxKzPHFBVKKpo9vvWUXRQwdTZy6iVOkyF26IPR+xDPzslzXOClKXUrWEh6La/EMpRwuMrWAbMIJFeDHOb56q4azgopoJmMJHo0yxGu0Ts4XszMACYRhlG6uK2AP5SYiOTp1zKPFjazXAdwLXyOvJurzy6KKuGJdSs/sj9+4uehgyRNOhehCSfg71tJJYwRvO2DDfLgaVEKOgZx58gEnJfhhz9D7rbvdZNhw/hCgtVNJaQF9Mdke2OPwWSo8i0/XNb9Bu/GRXqwMZrxDBhyzieocW40cwuzxWfzoi03aISdtQ1HtawH8+/sswviM1+B
Bruno Bronosky
  • 1,885
  • 1
  • 20
  • 26
3
ssh-keygen -r host.name.com

Will output the fingerprints for all configured public keys on an sshd instance.

These can then be put into DNS SSHFP records.

Mike Schroll
  • 131
  • 3
2

For checking the fingerprint that is present on Azure Devops, you can use

$ ssh-keygen -E md5 -lf .ssh/id_rsa.pub
2048 MD5:ba:42:24:87:d6:7b:71:a2:3e:b5:9a:31:b2:2c:e0:00 CrazyGirrafe@Australasia (RSA)
Pallav Jha
  • 121
  • 4
1

With OpenSSH 7.8 or greater, when using RSA keys, this will result in a matching fingerprint to the one that AWS is showing in their key list.

ssh-keygen -ef $path_to_private_key -m PEM | openssl rsa -RSAPublicKey_in -outform DER | openssl md5 -c
flickerfly
  • 971
  • 10
  • 14