-1

I have the fingerprint from the remote host which is said to be its public key fingerprint according to What is a SSH key fingerprint and how is it generated?.

Asking for the host fingerprint:

ssh-keygen -lf <(ssh-keyscan MY_SERVER.com 2>/dev/null)

gives for example:

2048 SHA256:asdfaewfbadsdasfasgasefasfasdvfth56sdghjum7 id_rsa (RSA)

and the following line:

ssh -o visualhostkey=yes -o FingerprintHash=SHA256 MY_SERVER.com

reaches the same:

2048 SHA256:asdfaewfbadsdasfasgasefasfasdvfth56sdghjum7 id_rsa (RSA)

and should be enough to say that the connection is the expected one.

On the other hand, I have the public (MY_PUBLIC_SSH_KEY) + private (MY_PRIVATE_SSH_KEY) ssh key pair at hand for the server. I can connect to the server with the private ssh key, and then with the right login_name, I do not need to enter a password anymore, which is the idea of the ssh key. Therefore, the public key that is saved on the server must also be the right one:

ssh -o visualhostkey=yes -o FingerprintHash=SHA256 -i MY_PRIVATE_SSH_KEY MY_LOGIN_NAME@MY_SERVER.com
# # or the same: 
# ssh -o visualhostkey=yes -o FingerprintHash=SHA256 -i MY_PRIVATE_SSH_KEY MY_LOGIN_NAME@MY_SERVER.com

But the fingerprint of the public ssh key MY_PUBLIC_SSH_KEY does not give the same fingerprint as that of the server. It does not use 2048 at the bit size of the underlying key, but the default 4096:

ssh-keygen -b 2048 -t rsa -lf id_rsa.pub

gives:

4096 SHA256:asfawefbrgaqeffaefafrew546rtghhdhdfhsert45y id_rsa (RSA)

The public key that I have at hand looks like:

ssh-rsa AAAABasfjjeiaj;jkaskl;dfkjsafe9w0fo-0oas[kfoamks;dfk...(4096 bits size)== MY_FILE_NAME

while that on the server (cat .ssh/id_rsa.pub) is:

ssh-rsa AAAABasfjieajfjaei;jfi;ajisejifjdfasdf(2048 bits size)...== ANOTHER_DIFFERENT_FILENAME

The fingerprints are not the same because the underlying key lengths and the added comment at the end are different. Yet, they should be the same thing. The -b parameter does not react to anything, and I can even use -t ecdsa and the fingerprint will still be the same, as if it always just gives something that is already fixed by the public key content itself.

ssh-keygen always defaults to 4096 bit key size, I need 2048, the -b parameter does not seem to work.

From this I see that either the public key has changed to the better 4096 standard and the ssh-keygen might default to that -t parameter which was used in the new public key while the server still outputs the old fingerprint for whatever reason, or the fingerprint of the public key cannot be the same as the fingerprint of the host since they are calculated from different bit sizes.

I also found that you can change the default of ssh-keygen, see Can you make default client key length larger for ssh-keygen?, but should it not just also work out with the -b parameter? 4096 is a good default, I do not want to change it. Or do I oversee something general here?

I know from other Q/A that it should already be enough to do the two steps above that reach the same fingerprint. But then I still want to know what I should do with the fingerprint of that 4096 bit public key at all if I do not need it for the successful comparison above.

I must have misunderstood something. With a key pair at hand, and the private key working, how can I find the "counterpart public key" on the server and compare fingerprints?

questionto42
  • 1,861
  • 3
  • 21
  • 52
  • I think you've just proven to yourself that whatever files you retrieved from the server—that you thought contained the server's ssh host keys—are not actually the files the server was getting its ssh host keys from. – Spiff Jan 24 '22 at 01:42
  • @Spiff the ssh private key can connect to the server. I have put that in the question now. I did not get them from the server, but from some other storage, perhaps I should rather get them from the server only. But then again, why is the private ssh key working if not for the reason that the public counterpart is on the server? And then why does this public key not show the same fingerprint that the server shows? – questionto42 Jan 24 '22 at 09:23
  • @Spiff Got it, see the answer, I needed to look for that user's public key in the authorized_keys file instead. And the one that I checked was really outdated and unused, therefore, you were right, I have proven myself that the ssh keys which I tried to match were not from the same key pair. – questionto42 Jan 24 '22 at 10:47
  • Your comments and Answer still sound off to me. It sounds like you're conflating a user's public key with the server's host key. The server has its own public/private key pair, usually in somewhere like `/etc/ssh/ssh_host_rsa_key.pub`. If you're fingerprinting an SSH host, that's the key you're fingerprinting, not something from a user's authorized_keys file. I'm also very confused by your talk about a central place where all the users' public keys are. That sounds like a very weird, very questionable setup to me. Each user's public key should be in their own `~/.ssh/id_rsa.pub`. – Spiff Jan 24 '22 at 17:32
  • @Spiff I appreciate your open words on this, I was also confused. It is not my structure but it is how it is implemented. I have not built it. It makes sense to have a central mapping file for different users that only links to the path with the secrets of choice for that user. There are more than 20 users in that file, therefore someone must have cleaned up the whole thing with this mapping list. The core of that answer is to look at the authorized_keys, the mapping list is just on top. – questionto42 Jan 24 '22 at 17:38
  • It sounds like someone set up your server in a weird way, so the Answer that worked for you won't work for anyone else. It will actually just confuse other people and lead them down the wrong path. I have half a mind to suggest you should delete this Question now that you have an answer, so it doesn't throw off other users. – Spiff Jan 24 '22 at 17:45
  • I also see your point. I ask for `ssh-keygen -lf <(ssh-keyscan MY_SERVER.com 2>/dev/null)` which is not linked to the user. And `ssh -o visualhostkey=yes -o FingerprintHash=SHA256 MY_SERVER.com` is not it either. Therefore your point is probably right, I mix up something here. Perhaps it is not the user mapping with a user dependent fingerprint, but just the last line that is the global server public key at that request? I disagree with deleting this since it is - again - not about the mapping that the core answer is about, but the authorized_keys file. I will check the fingerprint this week. – questionto42 Jan 24 '22 at 17:48
  • @Spiff You judge upon a professional environment here with your downvote. `Someone set up the server in a weird way` is likely wrong. If you do not know the idea well enough (neither do I), it does not mean that it *must be* weird. And again, I could also just drop that mapping table in the answer, the `authorized_keys` file paved the way to find the right public key which should add value for the community. – questionto42 Jan 24 '22 at 17:55
  • Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/133483/discussion-between-spiff-and-questionto42). – Spiff Jan 24 '22 at 18:35

2 Answers2

2

The -b parameter does not react to anything, and I can even use -t ecdsa and the fingerprint will still be the same, as if it always just gives something that is already fixed by the public key content itself.

Yes, that is actually how public keys work – all those parameters define the key itself, not the fingerprint, and they're pretty much immutable once the key has been generated.

The -b parameter literally defines the size of the key; if you have a 4096-bit sized RSA key, it will always be 4096 bits in size, and it will always be an RSA key. You can't just ask the software to cut it down to 2048 bits, or treat it like an ECDSA key.

So because the -l option in ssh-keygen -l instructs it to show information about an existing key, this means that if it says "4096" then it's a 4096-bit key and that's the end of it.

But those options are irrelevant to computing the fingerprint. SSH key fingerprints are nothing more than a direct SHA256 hash of the public key. If you look at the actual public-key file, it consists of "key-type key-data comment"; its fingerprint is simply SHA256() of the 'key-data' field, after Base64-decoding it. For example:

$ ssh-keygen -lf id_rsa.pub 
2048 SHA256:aOWdMg2Aoocj1yO90p9646d7ktNPIAjbjWm1PXTA9P0 root@frost (RSA)

$ awk '{print $2}' id_rsa.pub | base64 -d | openssl sha256 -binary | base64
aOWdMg2Aoocj1yO90p9646d7ktNPIAjbjWm1PXTA9P0=

As you can see, nowhere in the process even the key type is checked, much less type-specific parameters like the bit-size of the RSA prime.

While SSH servers typically have both an RSA key and an ECDSA key, the two are usually stored in different files, so if you want to see the fingerprint of the ECDSA key you have to copy the correct file. (The "public" files could be concatenated together into one file, then ssh-keygen would automatically list multiple fingerprints.)

u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
-1

This answer only shows how I got it done in the end and why theory and reality are a bit apart here, therefore I had to accept my own answer here without saying that the other answer is not helpful. For more typical settings, you will probably learn more from the other answer.

Server for user login only

The server was setup to let each user enter with its own "home of the public key"! This is an LDAP (Lightweight Directory Access Protocol) authentication system which is not used anymore on that server.

Step by step

How to find the user public key

I had to look up where to find the .ssh folder with the public key in a list of "password foldernames" mapped to a wide range of users:

etc/pass (long list of various users of the server with their passwords/secrets mapped):

... [long list]
proxy:x:13:13:proxy:/abc:/bin/sh
www:x:33:33:www:/xyz/www:/bin/sh
backup:x:34:34:backup:/zyx/backups:/bin/sh
... [long list]

My user www therefore had the .ssh in /xyz/www.

(Side-note: When looking through the server without seeing the directory tree in the terminal, you may use pwd to see where you are.)

Outdated public key in user .ssh

I switched to /xyz/www/.ssh. But in the folder, there was an outdated 2048 bit public key "id_rsa.pub", and not the server public key as in the first two commands of the question - checked with the fingerprint command again.

Server public key nowhere to find

I still do not know where that 2048 bit server key of the first two commands of the question is, and it is not the question here, but I guess that it is in /root which I cannot open in the terminal although it is there. There is also a root user that uses /root/.ssh for the secrets and passwords. Since the server is a VM, the working directories at start change with the users and different volumes are mounted for each user.

Found 4096 bit public key

The needed 4096 bit key was in the authorized_keys file in that same folder instead. The authorized_keys file looked like:

$ cat authorized_keys
... [longer list]
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAA... +some comment
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABA... +some comment
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABA... +some comment <-- my key

This last key in the list, "my key", is the one that I also have as a public key at hand, see above in the question (I changed the letters everywhere, but I take over the example from above):

ssh-rsa AAAABasfjjeiaj;jkaskl;dfkjsafe9w0fo-0oas[kfoamks;dfk...(4096 bits size)== MY_FILE_NAME

Side-note: MY_FILE_NAME is a comment that you add when making the key pair and is at your free choice, in my case the file_name, can be whatever.

And this key is different from the server key (first two examples in the question) but is the one that is checked when I connect to the server with my user www.

Matching fingerprints

Since the two public keys are the same, their fingerprints match as well, both

ssh-keygen -lf id_rsa.pub

give

4096 SHA256:asfawefbrgaqeffaefafrew546rtghhdhdfhsert45y id_rsa (RSA)

User public key

Therefore, this has all to do with a user public key that I need to check in an .ssh for that user only. It is not a server key, and the still existing server key is not used anymore and probably outdated (only 2048 bits). The rights and ssh keys for this server are all managed on user level. I guess that this has grown with the need to change to 4096 bit keys. Because of this user access structure, I had problems to find the 4096 bit public key on the server although it had to exist since my private key worked.

Wrap up

The question was changed from

How can I make a fingerprint from the public key that is the same as the server fingerprint?

to:

With a key pair at hand, and the private key working, how can I find the "counterpart public key" on the server and compare fingerprints?

because the first question was misleading. I could not know it better at the time of asking, though. It asked for the server public key fingerprint but in reality, that global server public key was not used anymore (outdated) and any access was arranged on user level with different .ssh subfolders, passwords and secrets for each different user. Please vote accordingly, meaning: the other answer is for the "earlier question", and though not accepted, it is of course helpful.

questionto42
  • 1,861
  • 3
  • 21
  • 52