When working with SSH keys across different operating systems, you might encounter surprising inconsistencies in how ssh-keygen
displays fingerprint digests. Here's what's happening:
# macOS behavior (10.10+):
$ ssh-keygen -l -E sha1 -f key.pem
2048 SHA1:x2ENPL+vzVdlgkIyu0tAhVQ+H4U key.pem.pub (RSA)
# Ubuntu behavior (14.04):
$ ssh-keygen -l -f key.pub
2048 29:ed:da:d3:5a:8c:78:4f:62:d3:fd:0c:77:5b:6d:d9 key.pub (RSA)
The difference comes from two factors:
- Newer OpenSSH versions (macOS) default to Base64 encoding
- Older versions (Ubuntu 14.04) use hexadecimal representation
For macOS users needing hex format:
# Convert Base64 to hex manually (bash version):
$ ssh-keygen -l -E sha1 -f key.pem | awk '{print $2}' | cut -d: -f2 | base64 -d | xxd -p | sed 's/../&:/g' | sed 's/:$//'
# Alternative using openssl:
$ openssl pkey -in key.pem -pubout | openssl sha1 -c
This Python script works on both systems:
import hashlib
import base64
import sys
def ssh_pubkey_sha1(pubkey_file):
with open(pubkey_file) as f:
key_line = f.readline().strip()
parts = key_line.split()
if len(parts) < 2:
raise ValueError("Invalid public key format")
key_bytes = base64.b64decode(parts[1])
sha1 = hashlib.sha1(key_bytes).hexdigest()
return ':'.join([sha1[i:i+2] for i in range(0, len(sha1), 2)])
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python ssh_sha1.py PUBLIC_KEY_FILE")
sys.exit(1)
print(ssh_pubkey_sha1(sys.argv[1]))
Consistent fingerprint formats are crucial when:
- Automating server deployments
- Implementing key rotation systems
- Building CI/CD pipelines with mixed environments
The solution using openssl
tends to be most portable across systems. For production environments, consider standardizing on SHA256 instead of SHA1 for better security.
When working with SSH keys across different operating systems, you might encounter inconsistent behavior when trying to get the SHA1 fingerprint of your public key. Here's what typically happens:
$ ssh-keygen -l -E md5 -f key.pem
2048 MD5:29:ed:da:d3:5a:8c:78:4f:62:d3:fd:0c:77:5b:6d:d9 key.pem.pub (RSA)
$ ssh-keygen -l -E sha1 -f key.pem
2048 SHA1:x2ENPL+vzVdlgkIyu0tAhVQ+H4U key.pem.pub (RSA)
The variation occurs because macOS (since 10.10) and Linux distributions implement the fingerprint display differently:
- macOS displays fingerprints in Base64 format by default
- Older Linux systems (like Ubuntu 14.04) show hexadecimal format
- Newer systems support both via the -E flag (md5|sha1|sha256)
For cross-platform compatibility, use these methods:
On macOS (Base64 to Hex Conversion)
$ ssh-keygen -l -E sha1 -f key.pem | awk '{print $2}' | cut -d':' -f2 | base64 -d | xxd -p
29edda3d5a8c784f62d3fd0c775b6dd9
On Modern Linux Systems
$ ssh-keygen -l -E sha1 -f key.pem
2048 SHA1:29:ed:da:d3:5a:8c:78:4f:62:d3:fd:0c:77:5b:6d:d9 key.pem.pub (RSA)
Alternative Method Using OpenSSL
This works consistently across platforms:
$ openssl pkey -in key.pem -pubout -outform DER | openssl sha1
SHA1(stdin)= 29:ed:da:d3:5a:8c:78:4f:62:d3:fd:0c:77:5b:6d:d9
Consistent SHA1 fingerprints are crucial for:
- Verifying host keys across team members' machines
- Automated deployment scripts
- Security audits and compliance checks
Always verify which format your system uses before comparing fingerprints between different machines.