A malicious user cannot exploit a publicly known fingerprint of a public key, because verification is not limited to comparing the fingerprint to a fixed value.
Server presents two pieces of information to a client:
- a public key
- a message encrypted with its private key (which exists only on the legitimate server)
On the client side the message is decrypted using the public key and its content is verified.
User is given an option to manually compare the fingerprint of the public key to a known value.
By comparing the public key fingerprint, user ensures it belongs to the server they want to connect. By decrypting the message, client application ensures the server "holds" the corresponding private key.
Knowledge of the public key or its fingerprint does not give an attacker any information about the server's private key (that's the most basic principle of public key cryptography).
If attacker planted a malicious server, it still would need to use a private key to encrypt communication with the client. Communication encrypted with this private key would require decryption with a corresponding public key (different to the legitimate one).
User can then compare the fingerprint of the public key used with the one of the legitimate server as published.
Of course if an attacker altered the information about the server's public key and replaced it with their own, that attack would work. Thus user must evaluate the trustworthiness level of the medium they learnt the fingerprint from. In simple words: if the fingerprint information is provided on an unencrypted HTTP site or through a compromised channel it cannot be trusted.
Historically default fingerprint was presented as 128-bit MD5 hash in the form of colon-separated hex values:
The default was later changed to SHA-256 written as:
An OpenSSH client allows asking for a specific hash using the option
FingerprintHash specified either in
.ssh/config or directly in command:
ssh -o FingerprintHash=md5 example.com