Discuss this help topic in SecureBlackbox Forum

Validate the key sent by the server

Unlike X.509 public key infrastructure and TLS, SSH uses a flat key scheme with no trust hierarchy (with extremely rare exceptions where X.509-based keys are used for authentication). The keys are therefore checked by comparing the key received from the server during an SSH negotiation to a cached copy or fingerprint of the trusted copy of the key communicated via different means (e.g. by confirming the hash of the key in advance by e-mail, over the phone, or via a secure web site).

When your SecureBlackbox SSH components receives a key from the server, it reports it via OnKeyValidate event. It is your responsibility, as a component user, to handle this event and perform key validation inside the handler.

(VERY) IMPORTANT: neglecting correct implementation of the validation routine, particularly by implementing it in 'by-pass' way by forcefully setting Validate to true without any checks, is extremely dangerous and will compromise the whole security of the SSH system you are building.

Key validation normally involves maintaining a local database of 'known' keys. In the simplest case this may be fulfilled by a CSV file. Each record should contain the server record (IP address and/or domain name) and the key record. The latter should at least contain some data which could serve as nearly-unique identifier of the key (SHA1 fingerprint is OK), but storing the whole key together with its algorithm might be a better option.

Note that a server might possess several keys, so your database format should be ready to take several records belonging to the same server.

When you receive a fresh server key in the OnKeyValidate handler, you must perform the following steps:

  1. Look for a cached copy of the server key in local database by the server and key identifiers.
  2. If the record was found, the genuineness of the key has been confirmed. Set Validate to true and exit the handler.
  3. If some server records were found, but none contains the identifier corresponding to the key received, an attack might be taking place. Warn the user and instruct them to confirm the key with server administrators. Never proceed without confirming as you might be connecting to a fake server! To increase user's willingness to confirm the key and not just skip this step, you might shift some responsibility about the consequences to them:
    "By clicking continue, I confirm that I have made all reasonable effort to verify the validity of the key (by contacting the server's or my company's IT person). I understand the risks of going ahead with the connection without duly check of the server key, and accept responsibility for all consequences that might arise from my negligence of this procedure".

    Note that this scenario might take place with a genuine server if a different public key algorithm was negotiated and a different key returned (see above). You might consider to design the UI of this step carefully so that your users got the right impression from this step and could take an educated action.

    If key confirmation routine was successful, add new key record to the database, set Validate to true and exit the routine. Otherwise, set it to false, and the components will terminate the connection for you.

  4. If the record was not found, you are likely to be connected to a new server. Ask your users to confirm the integrity of the key via other means. If the key is confirmed, add the key record to the database and set Validate to true.

You will find some TElSSHKey properties useful for the implementation of key validation:

  • SavePublicKey(): saves public part of the key to a buffer. Remember to always set the same KeyFormat to get the key in the same form. We recommend using kfOpenSSH or kfIETF.
  • Algorithm: returns the key algorithm (ALGORITHM_RSA, ALGORITHM_DSS, ALGORITHM_ECDSA).
  • Bits: returns key length.
  • FingerprintSHA1, FingerprintSHA1String: return key SHA1 fingerprint in byte array or string form.

Note: SSH servers often maintain several different private keys for different algorithms they support (e.g. RSA, DSS, ECDSA). If you change the set of public key algorithms supported locally, or change the algorithms' priorities, you might end up receiving a different public key not matching your local copy.

Note. Microsoft changed their implementation of .NET quick sort algorithm between .NET version 2 and 4.5, so you might end up receiving different keys even when migrating your project from .NET 2.0 to .NET 4.5 (and with no other changes in place!) This is because SSH components use sorting algorithms internally to sort algorithms by their priorities, and algorithms having the same priorities (e.g. RSA and DSS) might come in different order due to the algorithm changes.

How To articles about SFTP client

Discuss this help topic in SecureBlackbox Forum