FIPS Compatibility
bkyarnell opened this issue · 2 comments
Description of Issue/Question
Is FIPS supported?
Netmiko and relevant libraries version
cryptography 43.0.1
netmiko 4.4.0
paramiko 3.5.0
Netmiko device_type (if relevant to the issue)
cisco_xe
My code returns:
ValueError: [digital envelope routines] unsupported
when I attempt an SSH connect. Presume the error is with the paramiko and MD5 for ssh. Any thoughts?
Also tried adding:
from hashlib import md5
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
This seems like it's close, but still throws an error:
File "/usr/local/lib/python3.9/site-packages/netmiko/scp_handler.py", line 337, in file_md5
file_hash = hashlib.md5()
ValueError: [digital envelope routines] unsupported
No idea on FIPS.
You can probably modify that one line of code in scp_handler and have it be:
file_hash = hashlib.md5(usedforsecurity=False)
This is just used to hash the contents of the file.
A found a solution (well, hack) that works. Enabling FIPS does cause a problem with paramiko. This should be fixed proper, but until that occurs I found a solution from another article, "monkeypatch for FIPS". This just simply needs to be added to the top of your code. I have it after my import statements.
#Patch to allow paramiko to use SHA-256 vs MD5
import paramiko
from hashlib import sha256
paramiko.PKey.get_fingerprint = lambda x: sha256(x.asbytes()).digest()
This will allow the SSH transport to make use of SHA-256 vs. MD5. For those working on secure systems (I suspect a big part of the community!), use of MD5 isn't an option for transport. I'll post this back in paramiko comments too.
Your solution to update scp_handler for the file hash seems to work:
file_hash = hashlib.md5(usedforsecurity=False)
Thanks for that! I also came across this idea as a 'monkeypatch for md5'. This takes care of the file hash and doesn't cause any problems with FIPS.
Another alternative (this would require updates to the scp_handler code, but it works as a hack) would be to replace the md5 hashes with a hash that is sha2 compliant. SHA-512 is overkill in my example below. However, we have Cisco IOS_XE switches and the verify functions at the switch is either verify /md5 or verfiy /sha512. I guess Cisco figures they set the hash very high to keep from updating. SHA-256 is sufficient for most today, imo. I tested these updates to scp_handler and they work. Again, functional, but to fix proper would require updates to sections in scp_handler to report SHA-512 vs. MD5.
#file_hash = hashlib.md5()(usedforsecurity=False)
file_hash = hashlib.sha512()
and
#self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
) -> str:
self, base_cmd: str = "verify /sha512", remote_file: Optional[str] = None
) -> str:
With the above changes, everything seems to be working.
Hopefully, this is useful for someone else as well!