Paramiko Ssh Command Execution Failing with `Valueerror: [Digital Envelope Routines: Evp_Digestinit_Ex] Disabled for Fips`
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 Ssh_Client...
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)
1 Answer
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")