I don’t expect you to follow this post completely, but it’s so amazingly cool, I have to blog it. Consider the hashed sections of ~/.ssh/known_hosts file for (recent) OpenSSH clients, not including the public key parts:
|1|kFJT5z0x3ndyutgZ4E5pRk+ORBA=|hzXvdYUudo+qK9BGlFWtSAUXlXc= |1|8wo1+FO0hkATPgQZoeNHeIlvAjw=|dt/a9jz9CnLKP72j+Jr8MKMjgEE= |1|pvBQEKEGLnH0RCJr+8Dmqqnvlrs=|fJJvjyG/TmHFnuIX57nDThq/C4M= |1|HKV4DzgDkajXoUHf9B82JBu7J10=|c/K+MdJvWaZeJFs/W7iqhqo0wvE= |1|rtvQhRVnNanQZYkLUMbjoBGNhn0=|0U6a1LUQqLL6P1T2Wji3VWw69pw= |1|0ziSYi4c+xBXGEBZcNN1LMhYUc4=|qRSN5GSPyQi+fmaVz2zNwkmKoy8= |1|6nv6Vpk3AYgICHxJGVgVdsYRuq0=|fBNOIz1l3RW+N61jyDPunKX9n7E= |1|+b4uA+Mq7RHRAFW21qv8aO3rIRs=|1eizMri01IxEKrXquBnwTYP61Ow= |1|BkB0PZu2qtsLID/Ibe/D68gANQU=|qW6uAzcpecOOKNI4zEvngyfpGkI= |1|n+QrRn7QXeAJ5hRe2M8v8IspihE=|EqUxXdSeIF1cl1fQjl5zILebkGY= |1|BOKuKnWojy028tJf9Y671lws0d0=|SuBQJmJZp5JNVYG/rP9yb9ZhJcE= |1|WACsxtodOiM89kf4rNPLgF1CXZ4=|UTccVeLDZJF3wlH8V05XJNlsOBw= |1|o6FFoirXYblM7wBMdeJDYGMPI58=|5jJB7T7itY702ZHHByXtSpGk9SE=
The column fields are similar to that of the /etc/shadow file on GNU systems, except where the “$” is the column delimiter, “|” is in this case. If the string was “|1|o6FFoirXYblM7wBMdeJDYGMPI58=|5jJB7T7itY702ZHHByXtSpGk9SE=”, then the breakdown is as follows:
- |1- HASH_MAGIC. This tells the client that the host information has been salted and hashed with the SHA1 algorithm.
- |o6FFoirXYblM7wBMdeJDYGMPI58= This is the salt applied to the host- base 64 encoded 160-bit string.
- |5jJB7T7itY702ZHHByXtSpGk9SE= This is the base 64 encoded version of the hashed host
Now, if you want to get at the actual strings, not base 64 encoded, you could run the following command (I admit, not elegant, and could probably be better solved without nesting, and a single awk(1) statement, but I’ll get to that later):
% echo $(echo o6FFoirXYblM7wBMdeJDYGMPI58= | openssl base64 -d | xxd | cut -c 10-48) | sed 's/ //g' a3a145a22ad761b94cef004c75e24360630f239f % echo $(echo 5jJB7T7itY702ZHHByXtSpGk9SE= | openssl base64 -d | xxd | cut -c 10-48) | sed 's/ //g' e63241ed3ee2b58ef4d991c70725ed4a91a4f521
There you have it. Very cool. Now, the only question is how to apply the salt to the hostname, to get to the hash? I’m working that out, but I wasn’t motivated enough to get to it. Of course, there’s no application to this, that I can tell, unless you want to brute force the known_hosts file.