Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIPS Compatibility #3512

Open
bkyarnell opened this issue Oct 17, 2024 · 2 comments
Open

FIPS Compatibility #3512

bkyarnell opened this issue Oct 17, 2024 · 2 comments

Comments

@bkyarnell
Copy link

bkyarnell commented Oct 17, 2024

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
@ktbyers
Copy link
Owner

ktbyers commented Oct 18, 2024

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.

@bkyarnell
Copy link
Author

bkyarnell commented Oct 18, 2024

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants