1

I have a client-server pair and am trying to reproduce the warning:

REMOTE HOST IDENTIFICATION HAS CHANGED!

I am aware that one way to achieve this is to change the ecdsa key on the ssh server and force the server to use its ecdsa key to identify itself by editing Hostkey in /etc/ssh/sshd_config.

What I am curious about is if it is possible to do the same by changing the server's ecdsa public key in the client's known_hosts file. So far, if I change the key and try to ssh to the server the client just asks me to verify the key:

The authenticity of host '10.1.1.1' can't be established.

Does this mean that the server fingerprint or the public key is cached somewhere in the client?

3

The issue is likely that you are changing the host key in such a way as to make it unparsable. If you try using ssh -v [host] you'll probably see something like this:

debug1: /home/[user]/.ssh/known_hosts:1: parse error in hostkeys file

If you want to cause a verification error rather than a parse error that gets ignored, you'll have to change the key in a way that ssh still thinks it's valid. The way to do this depends on what type of key it is. You can force host key types with HostKeyAlgorithms (eg -o HostKeyAlgorithms=ssh-rsa). The most common host keys you'll run across with OpenSSH are RSA and ECDSA.


RSA

If you have an RSA host key, Thomas Pornin describes the public key format here:

00 00 00 07             The length in bytes of the next field
73 73 68 2d 72 73 61    The key type (ASCII encoding of "ssh-rsa")
00 00 00 03             The length in bytes of the public exponent
01 00 01                The public exponent (usually 65537, as here)
00 00 01 01             The length in bytes of the modulus (here, 257)
00 c3 a3...             The modulus

To avoid an invalid format error, you'll have to keep the string lengths and key type valid. OpenSSH also checks that the public exponent and modulus are not equal to 0, that the modulus is greater than 0, and that the modulus is at least 1024 bits. Here is an example key with a public exponent of 1 and a modulus of 21023 (note that this is not a valid RSA key, it just passes the checks OpenSSH uses for keys in known_hosts):

AAAAB3NzaC1yc2EAAAABAQAAAIEAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=

In general, you can change pretty much anything after the 33rd or so base64 character, as long as you keep it the same length and valid base64. All that's required is that the modulus is > 0 and at least 1024 bits.


ECDSA

You can find the key format in the RFC and SEC 1:

Let's break down this example key I just generated:

AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNLpVyqsu97ajvCDAcc8/W50xhG/Rt2qOxdiy05hAJJtwRTPZRJxrCLayFDWWkNY5ZICRQoYB6Fn7z42JPZNUaI=
00000013                                  Length of string (19 bytes)
65636473612d736861322d6e69737470323536    ASCII encoding of "ecdsa-sha2-nistp256" ("ecdsa-sha2-[identifier]")
00000008                                  Length of string (8 bytes)
6e69737470323536                          ASCII encoding of "nistp256" ("[identifier]")
00000041                                  Length of string (65 bytes)
04d2e9572aacbbdeda8ef08301c73cfd...       Q

Decoding Q according to SEC 1 section 2.3.4:
04                                                                 W
d2e9572aacbbdeda8ef08301c73cfd6e74c611bf46ddaa3b1762cb4e6100926d   X
c114cf651271ac22dac850d65a4358e59202450a1807a167ef3e3624f64d51a2   Y

The OpenSSL functions OpenSSH calls for ECDSA keys actually verify that the point is on the curve, so you'd have to do some math to change it to another valid public key. At that point you might as well just generate a new one using:

ssh-keygen -t ecdsa -f /tmp/key -N ''
cat /tmp/key.pub
rm /tmp/key{,.pub}

You can of course do this for RSA and other keys as well.

  • Thanks for the detailed response. After changing the key . >ssh-keygen -vvv -lF 10.1.1.1 . O/p: debug3: hostkeys_foreach: reading file "/Users/uname/.ssh/known_hosts" . It does not throw an error but does not print a fingerprint either. I think it is because of an invalid key like you said but it does not show an error that for some reason – abjoshi May 8 at 22:48
  • I should have clarified that, the parse error shows up when trying to ssh to the host using ssh -v. I also managed to overlook that you actually said it's an ecdsa key...but oh well, it's always fun learning stuff along the way. – AndrolGenhald May 8 at 22:52
  • Cool, It indeed shows a parse error on ssh -v. And yes, it is fun :-) – abjoshi May 9 at 1:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.