pythonencryptionsshparamiko

Determine what ciphers and key-exchange algorithms are available with Python Paramiko


I have an automated SFTP program written in Python using the Paramiko library. If I make a connection, I can show what ciphers and key exchange algorithms the transport is using. However, I am not sure this is the same thing as the algorithms and ciphers that are available.

Example:

>>> import paramiko
>>> ssh = paramiko.SSHClient()
>>> ssh.load_system_host_keys()
>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> ssh.connect("myhost.example.com", 22, username="xyzzy")
>>> t = ssh.get_transport()
>>> so = t.get_security_options()
>>> so.kex
('diffie-hellman-group14-sha1', 'diffie-hellman-group-exchange-sha1', 'diffie-hellman-group1-sha1')
>>> so.ciphers
('aes128-ctr', 'aes256-ctr', 'aes128-cbc', 'blowfish-cbc', 'aes256-cbc', '3des-cbc', 'arcfour128', 'arcfour256')

Is this the same as what is available? If not, is there any way to determine what is available programmatically?


Solution

  • The SecurityOptions class returned by the Transport.get_security_options() is:

    Simple object containing the security preferences of an ssh transport. These are tuples of acceptable ciphers, digests, key types, and key exchange algorithms, listed in order of preference.

    So it lists ciphers and kex algorithms that the Paramiko library supports (or a subset that you have configured/allowed).

    It is, what you (and Paramiko) are making available for the connection.

    What is actually used in the end is the most preferred cipher/kex algorithm that is also supported (available in your terms) by the server.


    To get list of supported algorithms, without connecting, you can use:

    import paramiko
    import socket
    
    opts = paramiko.transport.Transport(socket.socket()).get_security_options()
    print(opts.ciphers)
    print(opts.kex)