I try to find a script to decrypt (unhash) the ssh hostnames in the known_hosts file by passing a list of the hostnamses.

So, to do exactly the reverse of:

ssh-keygen -H -f known_hosts

Or also, to do the same as this if the ssh config HashKnownHosts is set to No:

ssh-keygen -R know-host.com -f known_hosts
ssh-keyscan -H know-host.com >> known_hosts

But without re-downloading the host key (caused by ssh-keyscan).

Something like:

ssh-keygen --decrypt -f known_hosts --hostnames hostnames.txt

Where hostnames.txt contains a list of hostnames.

  • The hostnames are part of the entries in known_hosts. What's to decrypt? – muru Dec 19 '14 at 18:21
  • 3
    I mean for a crypted known_hosts file. Where the ssh config HashKnownHosts is to Yes. I modified the title. – Xorax Dec 19 '14 at 18:26

Lines in the known_hosts file are not encrypted, they are hashed. You can't decrypt them, because they're not encrypted. You can't “unhash” them, because that what a hash is all about — given the hash, it's impossible¹ to discover the original string. The only way to “unhash” is to guess the original string and verify your guess.

If you have a list of host names, you can pass them to ssh-keygen -F and replace them by the host name.

while read host comment; do
  found=$(ssh-keygen -F "$host" | grep -v '^#' | sed "s/^[^ ]*/$host/")
  if [ -n "$found" ]; then
    ssh-keygen -R "$host"
    echo "$found" >>~/.ssh/known_hosts
done <hostnames.txt

¹ In a practical sense, i.e. it would take all the computers existing today longer than the present age of the universe to do it.

  • +1. I have a bash_completion file with a list of ssh files. The host keys for a lot of servers had changed, so I modified your script to give me a list of files which was 1) in my host list (generated) 2) in my known_hosts file (connected to at some point), so to know which hosts I most likely had to get new host keys for. Ended up with: grep "^..[dtn]" .ssh/ssh_hosts | while read H; do [ -n "$(ssh-keygen -F "$H")" ] && echo $H; done. Basically I knew the host name pattern most likely to be affected, and sent those server names through the script, outputting those in the know_hosts file. – sastorsl Nov 5 '20 at 7:58

The ssh-keygen(1) man page says for the -F hostname option:

Search for the specified hostname in a known_hosts file, listing any occurrences found. This option is useful to find hashed host names or addresses and may also be used in conjunction with the -H option to print found keys in a hashed format.

This seems to be what you want.

  • This return the line with the hashed hostname. I want to unhash it to replace it in the known_hosts file. It need a script to parse each line, un-hash it, and then replace it in the known_hosts file. – Xorax Dec 19 '14 at 18:34
  • 2
    @Xorax Yes, but with this command, you can retrieve the hashed hostname, and replace it in the known_hosts file with sed. – vinc17 Dec 19 '14 at 18:38

Im finding with these new encrypted files is to simply rm the known_hosts. Copy and paste the text to another location and put a comment above the encrypted known_hosts line about what ip is and the device. Trying to decrypt them just doesn't provide the info you need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.