2

Executing a command on remote machine using SSH is failing with the below error:

Traceback (most recent call last):
  File "ssh.py", line 4, in <module>
    ssh_client.connect(hostname='10.x.x.x', username='admin', password='password')
  File "/usr/lib/python3.6/site-packages/paramiko/client.py", line 407, in connect
    self, server_hostkey_name, server_key
  File "/usr/lib/python3.6/site-packages/paramiko/client.py", line 790, in missing_host_key
    key.get_name(), hostname, hexlify(key.get_fingerprint())
  File "/usr/lib/python3.6/site-packages/paramiko/pkey.py", line 151, in get_fingerprint
    return md5(self.asbytes()).digest()
ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS

The code snippet I'm using is as follows:

import paramiko
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(hostname='10.x.x.x', username='admin', password='password')
command = "sudo sh ~/script.sh"
ssh_client.exec_command(command)
Bharath M
  • 128
  • 1
  • 3
  • 14
  • I found this interesting blog https://www.gyanblog.com/security/how-build-patch-python-3.9.x-fips-enable/ which is talking about Patching the Python 3.9.x which kind of tells that the problem is with Python itself. – Bharath M May 17 '21 at 17:18

1 Answers1

2

I was facing this error too. This is because Paramiko uses MD5 encryption and the machine you want to connect to use FIPS, FIPS not allowed MD5 anymore.

So there is open PR in the Paramiko project.

In this issue above someone named neutronscott suggested editing the Pkey.py file.

Instead

 return md5(self.asbytes()).digest()

Change to

 return md5(self.asbytes(), usedforsecurity=False).digest()

So we can do something called 'Monkey patching'

Monkey patching is a technique to add, modify, or suppress the default behavior of a piece of code at runtime without changing its original source code.

This is worked for me:

class _PkeyChild(paramiko.PKey):
def get_fingerprint_improved(self):
    """
    Declare that the use of MD5 encryption is not for security purposes.
    This declaration is to overcome connection to servers with FIPS security standards.
    """
    return md5(self.asbytes(), usedforsecurity=False).digest()

...

paramiko.PKey.get_fingerprint = _PkeyChild.get_fingerprint_improved
connection = paramiko.SSHClient()
connection.set_missing_host_key_policy(paramiko.AutoAddPolicy())
connection.connect(hostname="host_name", username="username", password="password")
Moti Shaul
  • 73
  • 1
  • 8