How do I know if the 'usedforsecurity' flag is supported by hashlib.md5?
Question:
When I run the following on my Macbook, I get the error:
>>> import hashlib
>>> hashlib.md5(usedforsecurity=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: openssl_md5() takes no keyword arguments
But when I run it on my Linux box, it works!
>>> import hashlib
>>> hashlib.md5(usedforsecurity=False)
<md5 HASH object @ 0x7f763c1375d0>
My problem is, I need to run some safe, non-security related code on my FIPS enabled system (such as managing a cache of user requests which hashes the user query as an MD5 string). Using the usedforsecurity
flag prevents a FIPs exception.
This works fine, except when I want to test my code on my Macbook. My Macbook’s “libcrypto” library apparently doesn’t support this usedforsecurity
flag. Is there a good way to detect if the underlying C bindings behind hashlib.md5
support this flag or not?
Answers:
There is no way to explicitly check if a C-binding has a specific keyword argument:
>>> import inspect
>>> inspect.getargspec(hashlib.md5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/inspect.py", line 815, in getargspec
raise TypeError('{!r} is not a Python function'.format(func))
TypeError: <built-in function openssl_md5> is not a Python function
Here is the best that I could come up with, using try/except:
>>> import hashlib
>>> has_usedforsecurity_flag = False
>>> try:
... hashlib.md5(usedforsecurity=False)
... has_usedforsecurity_flag = True
... except Exception as e:
... print e
... # Doesn't have the flag.
...
<md5 HASH object @ 0x7f763c0b9bc0>
I ran into the same problem with FIPS and hashlib.md5(), but I was able to do this to check:
>>> import hashlib, inspect
>>> inspect.getargspec(hashlib.new)
ArgSpec(args=['name', 'string', 'usedforsecurity'], varargs=None, keywords=None, defaults=('', True))
On Python 3+, getargspec
is deprecated, so getfullargspec
should be used instead. The data structure is similar, but usedforsecurity
is in the kwonlyargs
field now.
>>> inspect.getfullargspec(hashlib.new)
FullArgSpec(args=['name', 'data'], varargs=None, varkw='kwargs', defaults=(b'',), kwonlyargs=['usedforsecurity'], kwonlydefaults={'usedforsecurity': True}, annotations={})
If you use hashlib.new('md5', usedforsecurity=False)
instead of hashlib.md5(usedforsecurity=False)
it will not raise exception, even if the keyword argument is not supported.
When I run the following on my Macbook, I get the error:
>>> import hashlib
>>> hashlib.md5(usedforsecurity=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: openssl_md5() takes no keyword arguments
But when I run it on my Linux box, it works!
>>> import hashlib
>>> hashlib.md5(usedforsecurity=False)
<md5 HASH object @ 0x7f763c1375d0>
My problem is, I need to run some safe, non-security related code on my FIPS enabled system (such as managing a cache of user requests which hashes the user query as an MD5 string). Using the usedforsecurity
flag prevents a FIPs exception.
This works fine, except when I want to test my code on my Macbook. My Macbook’s “libcrypto” library apparently doesn’t support this usedforsecurity
flag. Is there a good way to detect if the underlying C bindings behind hashlib.md5
support this flag or not?
There is no way to explicitly check if a C-binding has a specific keyword argument:
>>> import inspect
>>> inspect.getargspec(hashlib.md5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/inspect.py", line 815, in getargspec
raise TypeError('{!r} is not a Python function'.format(func))
TypeError: <built-in function openssl_md5> is not a Python function
Here is the best that I could come up with, using try/except:
>>> import hashlib
>>> has_usedforsecurity_flag = False
>>> try:
... hashlib.md5(usedforsecurity=False)
... has_usedforsecurity_flag = True
... except Exception as e:
... print e
... # Doesn't have the flag.
...
<md5 HASH object @ 0x7f763c0b9bc0>
I ran into the same problem with FIPS and hashlib.md5(), but I was able to do this to check:
>>> import hashlib, inspect
>>> inspect.getargspec(hashlib.new)
ArgSpec(args=['name', 'string', 'usedforsecurity'], varargs=None, keywords=None, defaults=('', True))
On Python 3+, getargspec
is deprecated, so getfullargspec
should be used instead. The data structure is similar, but usedforsecurity
is in the kwonlyargs
field now.
>>> inspect.getfullargspec(hashlib.new)
FullArgSpec(args=['name', 'data'], varargs=None, varkw='kwargs', defaults=(b'',), kwonlyargs=['usedforsecurity'], kwonlydefaults={'usedforsecurity': True}, annotations={})
If you use hashlib.new('md5', usedforsecurity=False)
instead of hashlib.md5(usedforsecurity=False)
it will not raise exception, even if the keyword argument is not supported.