When examining SSH authentication logs (/var/log/auth.log
), you'll often encounter entries like:
Dec 14 16:29:30 app sshd[22781]: Accepted publickey for dev from XXX.XXX.XX.XXX port XXXXX ssh2: RSA SHA256:pO8i...
This SHA256:
value represents the fingerprint of the client's public key in base64-encoded SHA256 format. It's a security feature introduced in OpenSSH 6.8+ to help administrators verify and track which keys are being used for authentication.
To manually verify this fingerprint against a known public key:
ssh-keygen -lf ~/.ssh/id_rsa.pub
256 SHA256:pO8i... user@host (RSA)
Or for a specific key file:
ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
The SHA256 fingerprint is calculated from the public key blob (RFC 4253 format) using:
SHA256(public_key_blob)
Example Python code to generate this fingerprint:
import hashlib
import base64
def calculate_sha256_fingerprint(pubkey):
# Remove key type and comment
key_data = pubkey.split()[1]
decoded = base64.b64decode(key_data)
sha256 = hashlib.sha256(decoded).digest()
return 'SHA256:' + base64.b64encode(sha256).decode('ascii').rstrip('=')
# Example usage:
pubkey = "ssh-rsa AAAAB3NzaC1yc2E... user@example.com"
print(calculate_sha256_fingerprint(pubkey))
This fingerprint is particularly useful for:
- Verifying that clients are using expected keys
- Detecting unauthorized key changes
- Auditing SSH access patterns
You can extract these fingerprints from logs for monitoring:
grep 'Accepted publickey' /var/log/auth.log | awk -F'SHA256:' '{print $2}' | sort | uniq
Older OpenSSH versions used MD5 fingerprints, which are less secure. The SHA256 format:
- Is more collision-resistant
- Uses base64 instead of hex for compactness
- Is the current recommended standard
To see both formats:
ssh-keygen -lvf ~/.ssh/id_rsa.pub
html
When examining SSH authentication logs, you'll frequently encounter entries like this:
Dec 14 16:29:30 app sshd[22781]: Accepted publickey for dev from XXX.XXX.XX.XXX port XXXXX ssh2: RSA SHA256:pO8i...
This SHA256 string represents the fingerprint of the client's public key used for authentication, presented in Base64 format. It serves as a security verification mechanism to help administrators identify and track which specific keys were used for authentication.
The fingerprint is generated using the following process:
# To manually generate from a public key file:
ssh-keygen -lf id_rsa.pub -E sha256
# Output format:
# 2048 SHA256:pO8i... user@host (RSA)
This matches exactly what appears in your auth.log entries. The fingerprint is calculated by:
- Taking the raw public key data (not the PEM format)
- Computing SHA256 hash
- Encoding the hash in Base64
These fingerprints are particularly useful for:
- Key rotation tracking: Identify when old keys are being used after rotation
- Security audits: Correlate authentication attempts with specific keys
- Troubleshooting: Verify which key was actually used during authentication
Here's how to verify if a key in your authorized_keys matches a log entry:
# Extract the public key fingerprint
grep "ssh-rsa AAAA..." ~/.ssh/authorized_keys | ssh-keygen -lf - -E sha256
You can also generate the fingerprint from private keys (useful when you don't have the public key):
ssh-keygen -y -f ~/.ssh/id_rsa | ssh-keygen -lf - -E sha256
For those managing multiple servers, here's a Python script to extract and analyze these fingerprints:
import re
from collections import defaultdict
def parse_auth_log(log_path):
pattern = r'Accepted publickey for .*? ssh2: RSA SHA256:(.*?)\s'
key_counts = defaultdict(int)
with open(log_path) as f:
for line in f:
match = re.search(pattern, line)
if match:
fingerprint = match.group(1)
key_counts[fingerprint] += 1
return key_counts
This script creates a frequency count of which keys are being used for authentication, helping identify potential security issues.
While these fingerprints are useful for administration:
- They don't replace proper key management procedures
- Frequent rotation of keys is still recommended
- Consider using certificates instead of raw keys for better traceability