When working with SSH authentication, it's crucial to ensure your private key (id_rsa
) and public key (id_rsa.pub
) form a valid cryptographic pair. Here are reliable methods to verify their relationship:
The most straightforward way to check key pair matching is by comparing their fingerprints:
# Generate fingerprint from private key
ssh-keygen -y -f id_rsa | ssh-keygen -lf -
# Get fingerprint from public key directly
ssh-keygen -lf id_rsa.pub
If both commands output identical fingerprints, the keys match. The -y
option tells ssh-keygen to extract the public key from the private key file.
For absolute certainty, perform a cryptographic verification:
# Create test file
echo "verification test" > testfile
# Sign with private key
openssl dgst -sha256 -sign id_rsa -out testfile.sig testfile
# Verify with public key
openssl dgst -sha256 -verify <(ssh-keygen -e -f id_rsa.pub -m PKCS8) -signature testfile.sig testfile
Successful verification outputs "Verified OK", confirming the key pair relationship.
RSA keys share the same modulus value. Compare them using:
# Get modulus from private key
openssl rsa -in id_rsa -noout -modulus | openssl md5
# Get modulus from public key
openssl rsa -in id_rsa.pub -pubin -noout -modulus | openssl md5
Identical MD5 hashes indicate matching keys.
For scripting purposes, here's a bash function to automate the check:
function verify_keypair() {
local private_key=$1
local public_key=$2
if [[ ! -f "$private_key" || ! -f "$public_key" ]]; then
echo "Error: Key files not found"
return 1
fi
private_fingerprint=$(ssh-keygen -y -f "$private_key" | ssh-keygen -lf - | awk '{print $2}')
public_fingerprint=$(ssh-keygen -lf "$public_key" | awk '{print $2}')
if [[ "$private_fingerprint" == "$public_fingerprint" ]]; then
echo "SUCCESS: Key pair matches"
return 0
else
echo "ERROR: Key pair mismatch"
return 1
fi
}
- Ensure key files have correct permissions (600 for private key)
- Verify the key format (PEM for private, OpenSSH for public)
- Check for passphrase protection that might prevent access
- Confirm you're examining the correct key files (common in multi-key environments)
For Python developers, here's how to verify using cryptography library:
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
def verify_key_pair(private_path, public_path):
with open(private_path, "rb") as f:
private_key = serialization.load_pem_private_key(
f.read(),
password=None,
)
with open(public_path, "rb") as f:
public_key = serialization.load_ssh_public_key(f.read())
# Compare public numbers
if (private_key.public_key().public_numbers() == public_key.public_numbers()):
return True
return False
When working with SSH or cryptographic systems, you'll often need to verify whether a given RSA private key (id_rsa
) matches its corresponding public key (id_rsa.pub
). This is crucial for security and troubleshooting purposes.
The most reliable way is to compare the modulus (the 'n' parameter in RSA) of both keys, which should be identical for a valid pair.
# Extract modulus from private key
openssl rsa -in id_rsa -noout -modulus | openssl md5
# Extract modulus from public key
openssl rsa -in id_rsa.pub -pubin -noout -modulus | openssl md5
If both commands output the same MD5 hash, your keys match.
For SSH keys specifically, you can use:
ssh-keygen -y -f id_rsa > generated_pub.key
diff generated_pub.key id_rsa.pub
No output means the keys match.
Here's a bash script that automates the verification:
#!/bin/bash
PRIVATE_KEY="id_rsa"
PUBLIC_KEY="id_rsa.pub"
if [ ! -f "$PRIVATE_KEY" ] || [ ! -f "$PUBLIC_KEY" ]; then
echo "Error: Key files not found"
exit 1
fi
PRIV_MOD=$(openssl rsa -in "$PRIVATE_KEY" -noout -modulus | openssl md5)
PUB_MOD=$(openssl rsa -in "$PUBLIC_KEY" -pubin -noout -modulus | openssl md5)
if [ "$PRIV_MOD" = "$PUB_MOD" ]; then
echo "SUCCESS: Key pair matches"
else
echo "ERROR: Key pair doesn't match"
exit 1
fi
Permission issues: Ensure your private key has proper permissions (600).
Key format problems: Convert between formats using:
ssh-keygen -p -f id_rsa -m pem
Passphrase-protected keys: You'll need to provide the passphrase during verification.
For integration into Python applications:
from Crypto.PublicKey import RSA
def verify_key_pair(private_key_path, public_key_path):
with open(private_key_path, 'r') as f:
priv_key = RSA.importKey(f.read())
with open(public_key_path, 'r') as f:
pub_key = RSA.importKey(f.read())
return priv_key.n == pub_key.n and priv_key.e == pub_key.e
# Usage
print(verify_key_pair('id_rsa', 'id_rsa.pub'))