How to Verify and Retrieve ECDSA Host Key for SSH Server Authentication


15 views

When connecting to an SSH server, you might encounter this common warning:

$ ssh example.com
Warning: the ECDSA host key for 'example' differs from the key for the IP address '10.0.0.2'
Offending key for IP in /Users/louis/.ssh/known_hosts:1

This indicates a mismatch between the server's current ECDSA host key and what your local machine has stored in its known_hosts file.

To examine the server's actual ECDSA host key, use one of these methods:

# Method 1: Using ssh-keyscan
ssh-keyscan -t ecdsa example.com

# Method 2: Verbose SSH connection
ssh -v example.com | grep "Server host key"

Example output:

example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJp3...

To find the conflicting entry in your known_hosts file:

# Find the specific line (in this case line 1)
sed -n '1p' ~/.ssh/known_hosts | ssh-keygen -l -f -

# Or search for the specific host
ssh-keygen -F example.com -f ~/.ssh/known_hosts

The SHA256 fingerprint provides a more readable verification:

ssh-keygen -lf <(ssh-keyscan -t ecdsa example.com 2>/dev/null)

Sample output:

256 SHA256:AbCdEfGhIjKlMnOpQrStUvWxYz1234567890 example.com (ECDSA)

Here's how to properly verify a server's ECDSA key:

# Step 1: Get the server's current key
SERVER_KEY=$(ssh-keyscan -t ecdsa example.com 2>/dev/null)

# Step 2: Get its fingerprint
echo "$SERVER_KEY" | ssh-keygen -lf -

# Step 3: Compare with what you have locally
ssh-keygen -F example.com -f ~/.ssh/known_hosts | ssh-keygen -lf -

For deeper inspection of ECDSA key parameters:

# Extract the base64 encoded key
KEY=$(ssh-keyscan -t ecdsa example.com 2>/dev/null | awk '{print $3}')

# Decode and view parameters
echo "$KEY" | base64 -d | openssl asn1parse -inform DER

When connecting to a server via SSH, you might encounter this common warning:

$ ssh example.com
Warning: the ECDSA host key for 'example' differs from the key for the IP address '10.0.0.2'
Offending key for IP in /Users/louis/.ssh/known_hosts:1

This indicates a host key mismatch between what your system expects and what the server presents.

To properly examine the ECDSA host key, try these approaches:

# Method 1: Using ssh-keyscan
ssh-keyscan -t ecdsa example.com

# Method 2: With verbose SSH output
ssh -v example.com 2>&1 | grep "Server host key"

# Method 3: Check known_hosts entry
ssh-keygen -l -f ~/.ssh/known_hosts

Once you have the key fingerprints, you can compare them:

# Get current server fingerprint
ssh-keyscan -t ecdsa example.com | ssh-keygen -lf -

# Get stored fingerprint for comparison
ssh-keygen -l -f ~/.ssh/known_hosts | grep example.com

If you've verified the new key is legitimate, update your known_hosts file:

# Remove old entry
ssh-keygen -R example.com

# Add new entry
ssh-keyscan -t ecdsa example.com >> ~/.ssh/known_hosts

For ECDSA keys (ecdsa-sha2-nistp256), you can extract more detailed information:

# Extract base64 encoded key
ssh-keyscan -t ecdsa example.com | cut -d' ' -f2- | base64 -d | hexdump -C

# View full key parameters (requires OpenSSL)
echo "ssh-keyscan -t ecdsa example.com | cut -d' ' -f2-" | \
  base64 -d | openssl asn1parse -inform DER

Here's a complete example for handling a host key change:

# 1. Get warning about key change
ssh server.example.com

# 2. Verify with server admin that key changed intentionally
# 3. Get new fingerprint through secure channel
expected_fingerprint="SHA256:1234abcd..."

# 4. Compare with actual server key
actual_fingerprint=$(ssh-keyscan -t ecdsa server.example.com | ssh-keygen -lf - | awk '{print $2}')

if [ "$expected_fingerprint" != "$actual_fingerprint" ]; then
  echo "WARNING: Fingerprints don't match!"
  exit 1
fi

# 5. Update known_hosts
ssh-keygen -R server.example.com
ssh-keyscan -t ecdsa server.example.com >> ~/.ssh/known_hosts