我怎么知道 hashlib.md5 是否支持 'usedforsecurity' 标志?

How do I know if the 'usedforsecurity' flag is supported by hashlib.md5?

当我 运行 在我的 Macbook 上执行以下操作时,出现错误:

>>> import hashlib
>>> hashlib.md5(usedforsecurity=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: openssl_md5() takes no keyword arguments

但是当我 运行 它在我的 Linux 盒子上时,它起作用了!

>>> import hashlib
>>> hashlib.md5(usedforsecurity=False)
<md5 HASH object @ 0x7f763c1375d0>

我的问题是,我需要在启用 FIPS 的系统上 运行 一些安全的、与安全无关的代码(例如管理用户请求的缓存,将用户查询散列为 MD5 字符串)。使用 usedforsecurity 标志可防止 FIPs 异常。

这工作正常,除非我想在我的 Macbook 上测试我的代码。我的 Macbook 的 "libcrypto" 库显然不支持这个 usedforsecurity 标志。有没有一种好方法来检测 hashlib.md5 背后的底层 C 绑定是否支持此标志?

无法显式检查 C 绑定是否具有特定关键字参数:

>>> 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

这是我能想到的最好的,使用 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>

我 运行 遇到了与 FIPS 和 hashlib.md5() 相同的问题,但我能够这样做来检查:

>>> import hashlib, inspect
>>> inspect.getargspec(hashlib.new)
ArgSpec(args=['name', 'string', 'usedforsecurity'], varargs=None, keywords=None, defaults=('', True))

在 Python 3+ 上,getargspec 已弃用,因此应改用 getfullargspec。数据结构类似,但 usedforsecurity 现在在 kwonlyargs 字段中。

>>> inspect.getfullargspec(hashlib.new)
FullArgSpec(args=['name', 'data'], varargs=None, varkw='kwargs', defaults=(b'',), kwonlyargs=['usedforsecurity'], kwonlydefaults={'usedforsecurity': True}, annotations={})

为了扩展 Tim 的回答,如果您使用 hashlib.new('md5', usedforsecurity=False) 而不是 hashlib.md5(usedforsecurity=False),即使不支持关键字参数,也不会引发异常。