Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230

 

 

 

SSH fingerprint don't match, and putty doesn't complain

If none of the specific sub-forums seem right for your thread, ask here.
Post Reply
Message
Author
banderas20
Posts: 111
Joined: 2016-11-10 15:30

SSH fingerprint don't match, and putty doesn't complain

#1 Post by banderas20 »

Hello all,

I run a ssh session from Windows to a Debian server and the host fingerprint is already added (Putty doesn't complain).

According to Putty, it keeps / caches the host key fingerprint in Windows Registry

Code: Select all

HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys
If I navigate to that folder, I can't see the following:

Code: Select all

Key:ssh-ed25519@blah
Value: 0x21237be85809213e73d6be7d1b09dda5cd6f60f38dd117360493525a0352618c,0x1a63981c9eac24f47036bb5de701fe3e4b6fc0b92af6c0ebadd118fce369fd85

Key: ssh-ed25519@blah
Value: 0x2516d655ce74a570d794d298d0f6488d445b35fec8116ee8f3b31840e1f170b9,0x471b29aedac798c57f025113e4fccb0ebf178a1cba81a9560fd820c31cf785e
OK. So some of these must be the host fingerprints.

I logon to the server and go to /etc/ssh and issue "ssh-keygen -l -E md5 -f ssh_host_rsa_key.pub"
giving me

Code: Select all

2048 MD5:f6:da:b5:da:21:19:6e:74:b4:ed:a4:94:bc:51:fa:c4
if I do "ssh-keygen -l -E md5 -f ssh_host_ed25519_key.pub"
it gives:

Code: Select all

256 MD5:51:24:d2:8b:11:61:c5:21:22:e6:ce:7b:ca:8a:d2:bd
None of these codes match. ¿What am I missing?

Thanks!

cronoik
Posts: 310
Joined: 2015-05-20 21:17

Re: SSH fingerprint don't match, and putty doesn't complain

#2 Post by cronoik »

The verify_host_key function of [1] seems not to call any fingerprint function. I assume that maybe the values you see in the windows registry are the publickeys encoded as hex.

[1] https://github.com/KasperDeng/putty/blo ... winstore.c
Have a nice day!

banderas20
Posts: 111
Joined: 2016-11-10 15:30

Re: SSH fingerprint don't match, and putty doesn't complain

#3 Post by banderas20 »

cronoik wrote:The verify_host_key function of [1] seems not to call any fingerprint function. I assume that maybe the values you see in the windows registry are the publickeys encoded as hex.

[1] https://github.com/KasperDeng/putty/blo ... winstore.c
You mean encoded as hex WITHOUT MD5 hash, ¿no? Because both formats are in hex, AFAIK....

Thanks!

cronoik
Posts: 310
Joined: 2015-05-20 21:17

Re: SSH fingerprint don't match, and putty doesn't complain

#4 Post by cronoik »

Yes I think that is the case. The already mentioned function verify_host_key get's a pointer to the retrieved public key from the server and is not a applying a fingerprint function to that key. In line 443 is the comparison happening between the registry value and that key. Therefore I think putty stores the public key and not the fingerprint of the public key in the registry.

Of course it is possible that I have overlooked something but this is how it looks like for me after the time I have invested in the code.
Last edited by cronoik on 2018-07-27 21:01, edited 1 time in total.
Have a nice day!

banderas20
Posts: 111
Joined: 2016-11-10 15:30

Re: SSH fingerprint don't match, and putty doesn't complain

#5 Post by banderas20 »

cronoik wrote:Yes I think that is the case. The already mentioned function verify_host_key get's a pointer to the retrieved public key from the server and is not a applying a fingerprint function to that key. In line 443 is the comparison happening between the registry value and that key. Therefore I think putty stores the public key and not the fingerprint the public key in the registry.

Of course it is possible that I have overlooked something but this is how it looks like for me after the time I have invested in the code.
It's strange, because I've tried to hash online the full public key and it doesn't give me the same results. With none of the algorithms available in the webpages (MD5, SHA, etc...). It's weird...

Thanks.

cronoik
Posts: 310
Joined: 2015-05-20 21:17

Re: SSH fingerprint don't match, and putty doesn't complain

#6 Post by cronoik »

It is not weird you just assumed that the public key is stored in the registry as it is stored on your server, which is not the case. I did some more research and found out that putty stores the public keys in his own format [1] and not in the openssh format which is the format of your host key on the server. You need to convert the registry entry from the putty key format to the openssh key format to be able to compare the fingerprints.
I have slightly modified a script of Mark Grandi [2] which you can use to make the conversion:

Code: Select all

#!/usr/bin/env python3
#
# script that converts between
# openSSH 'known hosts' to what putty
# stores in the registry for its known hosts
#
#
# written by Mark Grandi, March 27, 2014
# ruined by cronoik :(

import binascii
import struct
import base64
import io
import sys
import argparse
import os, os.path
import collections
import re
import socket
import math

# represents the data that would go inside the registry key for the putty known hosts
# add your registry values here:
keyName = 'rsa2@2.....'
exponent = '0x10001'
modulus = '0x.......'


PuttyKnownhostEntry = collections.namedtuple("PuttyKnownhostEntry", ["keyName", "exponent", "modulus"])

yourkey = (PuttyKnownhostEntry(keyName, exponent,modulus))

def main():
    ''' figures out what function to call
    @param args - the argument parser Namespace object we got from parse_args()
    '''
    puttyToOpenSSH()


def puttyToOpenSSH():
    ''' converts putty known hosts entries to openSSH ones
    @param args - the argument parser Namespace object we got from parse_args()
    '''

    puttyEntries = []
    
    puttyEntries.append(yourkey)    
    
    # now go through each entry and convert it to a openssh line
    openSshLines = []
    for iterEntry in puttyEntries:

        # parse the key name, which has the hostname or ip, port, and algorithm
        # it looks like: 'rsa2@60101:mgrandi.no-ip.org'
        alg = iterEntry.keyName.split("@")[0]
        opensshAlg = ""
        if alg == "rsa2":
            opensshAlg = "ssh-rsa"
        elif alg == "dsa":
            opensshAlg = "ssh-dss"

        secondPart = iterEntry.keyName.split("@")[1]
        port = secondPart.split(":")[0] # putty always stores the port

        hostOrIp = secondPart.split(":")[1]
        hostName = hostOrIp

        try:
            addrList = socket.getaddrinfo(hostOrIp, port)
            hostName = addrList[0][4][0]
        except OSError as e:
            print("#WARNING: error when trying to resolve '{}:{}', error: '{}'\n\n".format(hostOrIp, port, e))
            hostName = hostOrIp
            

        # now calculate the data that it stores
        resultBytes = io.BytesIO()

        resultBytes.write(struct.pack(">i", 7)) # write that there is a 7 byte algorithm identifier

        resultBytes.write(opensshAlg.encode("utf-8")) # write algorithm identifier

        expInt = int(iterEntry.exponent[2:], 16)

        # how many bytes does it take to store this exponent?
        numBytes = math.ceil(int(expInt).bit_length() / 8)

        # write length of exponent
        resultBytes.write(struct.pack(">i", numBytes))

        # write exponent
        resultBytes.write(struct.pack(">{}s".format(numBytes), int(expInt).to_bytes(numBytes, "big")))


        modulusData = binascii.unhexlify(iterEntry.modulus[2:])

        # here we have to 'add' a b'\x00' byte to the start of this, because i guess we are padding the modulus
        # to match the RSA key modulus, see my comment later on in this file)
        modulusData = b'\x00' + modulusData

        # write length of modulus
        resultBytes.write(struct.pack(">i", len(modulusData)))

        # write modulus
        resultBytes.write(modulusData)


        # base64 it
        result = base64.b64encode(resultBytes.getvalue())

        # now we have the openssh line
        # put it in our list
        # (like [68.98.45.184]:23 ssh-rsa AAAAB3.....)
        openSshLines.append("[{}]:{} {} {}".format(hostName, port, opensshAlg, result.decode("utf-8")))


    for iterEntry in openSshLines:
        print(iterEntry + "\n")


if __name__ == "__main__":
    main()
I haven't tested it with ed25519 keys because I don't have registry entries of servers with such a key. In case it doesn't work try to set opensshAlg = "ed25519" or look for a script which does the conversion between the putty key format and the openssh key format.

[1] https://unix.stackexchange.com/question ... -putty-key
[2] https://github.com/mgrandi/openssh-putt ... -converter
Have a nice day!

banderas20
Posts: 111
Joined: 2016-11-10 15:30

Re: SSH fingerprint don't match, and putty doesn't complain

#7 Post by banderas20 »

Hello.

Yes. I have also done some research and It's not trivial how Putty stores the fingerprint. I'm not the only one wondering how it's done

https://stackoverflow.com/questions/448 ... -host-keys

At least I know I was not forgetting or bypassing some basic concept.

I'll try your script.

Thanks a million for your effort!

Post Reply