1. Overview
Secure Shell (SSH) is a fundamental tool for remote system administration and secure data communication in Linux environments. One of the essential aspects of SSH security is the verification of server identities through fingerprints. SSH fingerprints serve as unique identifiers that enable us to confirm the authenticity of remote servers before establishing a connection, thereby preventing man-in-the-middle attacks.
In this tutorial, we’ll discuss the concept of SSH fingerprints and their different formats in Linux. First, we’ll explore the common MD5 and SHA-256 formats, as well as how to retrieve SSH fingerprints. After that, we’ll delve deeper into identifying and confirming them. Lastly, we’ll highlight best practices for SSH fingerprint management.
2. What Is an SSH Fingerprint?
An SSH fingerprint is a cryptographic hash value that uniquely identifies an SSH server. In essence, it serves as a digital signature that helps verify the authenticity and integrity of a remote server before establishing an SSH connection.
2.1. How SSH Fingerprints Are Generated
When an SSH server is set up, it generates a pair of cryptographic keys: a public key and a private key. The public key is then used to generate the fingerprint, which is a unique representation of the server’s identity. This fingerprint can be retrieved and compared during the SSH connection process to ensure the server’s authenticity.
2.2. How to Retrieve SSH Fingerprints
To retrieve SSH fingerprints, we can use the ssh-keygen command, followed by the -l option for listing the fingerprint of a public key file and -f for specifying the filename of the key file:
$ ssh-keygen -lf ~/.ssh/id_rsa.pub
3072 SHA256:2H3LNvKaYyuMheDJ1geii/G5A9+7wxF2pU/FIxrJyFI username@hostname (RSA)
SHA-256 is the default hash algorithm for generating SSH key fingerprints in newer versions of ssh-keygen, although there are older algorithms like MD5 and SHA-1.
3. Identifying Different Formats of SSH Fingerprints
SSH fingerprints can be represented in various formats. Each uses a different hash algorithm to compute the fingerprint. Let’s consider three commonly used SSH formats: MD5, SHA-1, and SHA-256.
3.1. MD5 Format
The MD5, Message Digest Algorithm 5, format computes a 128-bit hash value, often represented as a 32-character hexadecimal number:
$ ssh-keygen -lf ~/.ssh/id_rsa.pub -E MD5
3072 MD5:61:cb:3e:0e:5a:51:50:b9:10:2b:3d:52:3a:58:12:c4 username@hostname (RSA)
MD5 offers simple and fast computation and enjoys wide support for compatibility with older systems. However, it has significant drawbacks, including vulnerability to collision attacks. Therefore, it’s considered weak and insecure for cryptographic purposes.
3.2. SHA-1 Format
The SHA-1, Secure Hash Algorithm 1, format computes a 160-bit hash value, represented as a base64-encoded string:
$ ssh-keygen -lf ~/.ssh/id_rsa.pub -E SHA1
3072 SHA1:51kuIF7NQ5O9zZsj6YDjnQj+Khg username@hostname (RSA)
SHA-1 also offers faster computation compared to SHA-256 and is compatible with older systems. However, it’s vulnerable to collision attacks, which makes it weak and less secure for cryptographic use.
3.3. SHA256 Format
The SHA-256, Secure Hash Algorithm 256-bit, format computes a 256-bit hash value. Similarly, it’s represented as a 64-character hexadecimal number:
$ ssh-keygen -lf ~/.ssh/id_rsa.pub -E SHA256
3072 SHA256:2H3LNvKaYyuMheDJ1geii/G5A9+7wxF2pU/FIxrJyFI username@hostname (RSA)
We’ve established that SHA-256 is the default hash algorithm in newer versions of ssh-keygen. It offers strong cryptographic security and is resistant to collision attacks. However, it has a slower computation time compared to MD5 and SHA-1 and may not be supported on very old systems.
3.4. Comparison
Let’s look at the three formats once again in a table:
Hash Algorithm
Length
Security Level
Speed
Compatibility
MD5
128-bit
Weak
Fast
High
SHA-1
160-bit
Weak
Moderate
High
SHA-256
256-bit
Strong
Slow
Moderate (modern systems)
In this table, we notice a distinct trade-off between security level and speed among the three options.
4. Comparing Fingerprints Across Different Formats
Verifying SSH fingerprints is an important step in ensuring the security of SSH connections. By comparing the fingerprint presented by the server with a trusted fingerprint stored on the client side, we can confirm that we’re connecting to the intended server and not a malicious actor attempting a man-in-the-middle attack. This verification process helps safeguard sensitive data and prevent unauthorized access to remote systems.
4.1. Comparing the Same Formats
If both formats utilize the same hash algorithm, we can manually compare them. For a successful connection, the entire string of characters in both fingerprints must match exactly.
Alternatively, a simple script can automate the string comparison:
$ cat compare_fingerprints.sh
#!/bin/bash
# Assign the content of the files to variables
trusted_fingerprint=$(cat "$1")
server_fingerprint=$(cat "$2")
# Perform the comparison
if [[ "$server_fingerprint" == "$trusted_fingerprint" ]]; then
echo "Fingerprints match!"
else
echo "Fingerprints differ!"
fi
The script compares the server fingerprint with the trusted fingerprint using string comparison (==).
Supposing we already have both fingerprints stored in separate files, let’s run the script:
$ bash compare_fingerprints.sh trusted_server.fingerprint server_fingerprint.txt
Fingerprints match!
If the keys match, then it’s safe to proceed with the connection.
4.2. Comparing Different Formats
Conversely, we can’t directly compare fingerprints in different formats. First, we’ll need to retrieve the fingerprint in the desired format using the -E option we used earlier, or the -o option with ssh:
$ ssh -o "FingerprintHash sha256" testhost
The authenticity of host 'testhost (102.88.82.213)' can't be established.
ECDSA key fingerprint is SHA256:2H3LNvKaYyuMheDJ1geii/G5A9+7wxF2pU/FIxrJyFI.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Similarly, we can request md5:
$ ssh -o "FingerprintHash md5" testhost
The authenticity of host 'testhost (102.88.82.213)' can't be established.
ECDSA key fingerprint is MD5:61:cb:3e:0e:5a:51:50:b9:10:2b:3d:52:3a:58:12:c4.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
After that, we can use the same script we created earlier to compare the two fingerprints.
A more advanced approach involves downloading the public key to a system that supports different hash formats:
$ ssh-keyscan testhost >testhost.ssh-keyscan
# testhost:22 SSH-2.0-OpenSSH_9.3p2 Debian-1
# testhost:22 SSH-2.0-OpenSSH_9.3p2 Debian-1
# testhost:22 SSH-2.0-OpenSSH_9.3p2 Debian-1
# testhost:22 SSH-2.0-OpenSSH_9.3p2 Debian-1
This command downloads the public key information for the testhost server and saves it in the testhost.ssh-keyscan file.
Next, we can display the stored keys:
$ cat testhost.ssh-keyscan
testhost ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqdlbQeE1VnEmQ...
testhost ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYA...
testhost ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFkDA9bw6BDTByni...
The output contains the raw public key data, which is useful for various purposes, including populating the known_hosts file or verifying the server’s authenticity.
After that, we analyze the keys stored in testhost.ssh-keyscan and get their fingerprint with the same method as before:
$ ssh-keygen -lf testhost.ssh-keyscan -E sha256
3072 SHA256:+dB/HijG7O0jB5cmzcgp5xK3ZkA3d295Zl+2Bo+gKhk testhost (RSA)
256 SHA256:2H3LNvKaYyuMheDJ1geii/G5A9+7wxF2pU/FIxrJyFI testhost (ECDSA)
256 SHA256:4zT4lmi0U8DWX1+HfDPa9g2z0nuo+/3carB4lxusq1U testhost (ED25519)
This displays the key information along with its SHA-256 fingerprint.
Finally, we can compare the fingerprints using the compare_fingerprints.sh script we created earlier.
5. Best Practices and Considerations
Verifying SSH fingerprints is a critical step in securing remote connections. We should always ensure that we’re establishing connections with the intended servers to avoid potential security risks.
5.1. Obtaining Trusted Fingerprints
It’s important to acquire trusted fingerprints from reliable sources. This could be the server’s official documentation, secure channels provided by the administrator, or a direct transfer from a trusted individual. We should be wary of fingerprints we find online or from untrusted sources, as attackers could tamper with them to compromise our connection.
5.2. Verifying Fingerprint Matches
Before proceeding with the connection, we should meticulously compare the fingerprints using the methods we discussed earlier. Even a single typo or mismatch in characters can be a red flag. If the fingerprints don’t match, we should exercise caution. It might also help to contact the server administrator to verify the correct fingerprint or abort the connection entirely if suspicion arises.
5.3. SSH Client Configuration
Additionally, some SSH clients allow us to configure stricter host-checking settings. Enabling these settings adds an extra layer of security by prompting us to confirm the fingerprint for every new server we connect to. This process enhances security, although it can become inconvenient for frequently accessed servers.
6. Conclusion
In this article, we learned that SSH fingerprints are generated using various cryptographic algorithms such as MD5, SHA-1, and SHA-256, each with its own advantages and potential vulnerabilities. While MD5 and SHA-1 are widely supported and fast, they are considered less secure and are being phased out in favor of SHA-256 and other advanced algorithms.
When verifying SSH fingerprints, it’s essential to compare them accurately, especially if the hash formats differ. Finally, utilizing commands like ssh-keygen with the -E option or ssh-keyscan can help retrieve and compare fingerprints across various formats, ensuring we’re connecting to the intended server.