我有一个python应用程序,它包含Python和Libcrypto以及LibSSL共享对象。该应用程序是使用Openssl Fips Module 2.0构建的。这些共享对象由Python的请求模块和urllib3用于发出TLS请求。
我在构建应用程序的环境中启用了 OPENSSL_FIPS 标志。现在,如果想要检查共享对象是否已启用fips模式,当我将它们带出开发环境并将它们放入另一台机器时,我该怎么办呢?
如何检查是否启用了fips模式?如果不是,我如何为这些共享对象启用fips模式?
可能有用的其他详情:
OpenSSL版本:1.0.2h(从源代码构建)
Fips模块:2.0.12(从源代码构建)
Python:3.6
操作系统:Ubuntu 16.04 LTS
如果需要任何其他详细信息,请与我们联系。
谢谢!
答案 0 :(得分:3)
我使用常规标记构建了 OpenSSL-fips 模块(例如: no-asm , shared ,一些古老的密码禁用):
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049320993]> ls ssl/build/bin ssl/build/lib ssl/build/bin: c_rehash openssl ssl/build/lib: engines libcrypto.a libcrypto.so libcrypto.so.1.0.0 libssl.a libssl.so libssl.so.1.0.0 pkgconfig
并开始玩它:
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049320993]> ssl/build/bin/openssl version OpenSSL 1.0.2h-fips 3 May 2016 (Library: OpenSSL 1.0.2g 1 Mar 2016)
请注意" (图书馆:OpenSSL 1.0.2g 2016年3月1日) "部分。 (存在)指出 openssl 可执行文件是正常的(预期版本),但它使用错误 libcrypto (它&默认情况下安装在系统上的那个 - 在 / lib 下 - 并且通常不会使用 FIPS 支持构建一个)。
它必须加载我们的库,这是通过设置 LD_LIBRARY_PATH 来完成的(通过在构建时设置env var也可以实现相同的行为OpenSSL ,它会在 openssl 可执行文件中设置 rpath ,但我忘了,而且我不想再次构建它:
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049320993]> LD_LIBRARY_PATH=ssl/build/lib ssl/build/bin/openssl version OpenSSL 1.0.2h-fips 3 May 2016
现在,设置成功,让我们深入了解 OPENSSL_FIPS env var:
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049320993]> LD_LIBRARY_PATH=ssl/build/lib ssl/build/bin/openssl md5 ./code.py MD5(./code.py)= d41d8cd98f00b204e9800998ecf8427e [cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049320993]> LD_LIBRARY_PATH=ssl/build/lib ssl/build/bin/openssl sha1 ./code.py SHA1(./code.py)= da39a3ee5e6b4b0d3255bfef95601890afd80709 [cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049320993]> OPENSSL_FIPS=1 LD_LIBRARY_PATH=ssl/build/lib ssl/build/bin/openssl sha1 ./code.py SHA1(./code.py)= da39a3ee5e6b4b0d3255bfef95601890afd80709 [cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049320993]> OPENSSL_FIPS=1 LD_LIBRARY_PATH=ssl/build/lib ssl/build/bin/openssl md5 ./code.py Error setting digest md5 139778679649944:error:060A80A3:digital envelope routines:FIPS_DIGESTINIT:disabled for fips:fips_md.c:180:
如上所示, md5 哈希行为受 OPENSSL_FIPS env var的影响(当 FIPS 模式打开时,其用法为不允许)。
备注强>:
由于 OPENSSL_FIPS env var是在 openssl 可执行级别处理的,它将被绕过(因为 libcrypto 将直接使用),它&# 39;对目前的情况毫无用处,所以我们必须更深入。这些是在加载的 libcrypto 实例中控制 FIPS 模式的函数:
它们将用于读/写 FIPS 模式。为了测试是否真的设置了 FIPS 模式,将使用 md5 哈希(来自上面的示例)。
code.py :
#!/usr/bin/env python3
import sys
import ssl
import ctypes
libcrypto = ctypes.CDLL("libcrypto.so.1.0.0")
fips_mode = libcrypto.FIPS_mode
fips_mode.argtypes = []
fips_mode.restype = ctypes.c_int
fips_mode_set = libcrypto.FIPS_mode_set
fips_mode_set.argtypes = [ctypes.c_int]
fips_mode_set.restype = ctypes.c_int
text = b""
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
print("OPENSSL_VERSION: {:s}".format(ssl.OPENSSL_VERSION))
enable_fips = len(sys.argv) > 1
print("FIPS_mode(): {:d}".format(fips_mode()))
if enable_fips:
print("FIPS_mode_set(1): {:d}".format(fips_mode_set(1)))
print("FIPS_mode(): {:d}".format(fips_mode()))
import hashlib
print("SHA1: {:s}".format(hashlib.sha1(text).hexdigest()))
print("MD5: {:s}".format(hashlib.md5(text).hexdigest()))
备注强>:
import hashlib
语句位于设置 FIPS 模式后(而不是在文件开头,因为它应该是),因为 hashlib 在导入时执行了一些缓存 ,因此它在导入时捕获 FIPS 值,并且不会如果之后发生变化,请小心<强>输出强>:
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049320993]> LD_LIBRARY_PATH=ssl/build/lib ./code.py Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux OPENSSL_VERSION: OpenSSL 1.0.2h-fips 3 May 2016 FIPS_mode(): 0 FIPS_mode(): 0 SHA1: da39a3ee5e6b4b0d3255bfef95601890afd80709 MD5: d41d8cd98f00b204e9800998ecf8427e [cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049320993]> LD_LIBRARY_PATH=ssl/build/lib ./code.py 1 Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux OPENSSL_VERSION: OpenSSL 1.0.2h-fips 3 May 2016 FIPS_mode(): 0 FIPS_mode_set(1): 1 FIPS_mode(): 1 SHA1: da39a3ee5e6b4b0d3255bfef95601890afd80709 fips_md.c(149): OpenSSL internal error, assertion failed: Digest Final previous FIPS forbidden algorithm error ignored Aborted (core dumped)
如图所示,通过 ctypes 设置 FIPS 模式,真的设置它。
我不知道为什么会出现段错误,但 md5 相关代码仅用于测试目的,因此在生产中不需要它。
我记得在某些 Lnx 版本(可能是 RH )上,也可以设置 FIPS 模式(系统全局) ,通过编辑一些条目(在 / proc 下?),但我无法记住它。
更优雅的方法将为2个函数公开 Python 包装器。
检查 [Python]: Issue 27592: FIPS_mode() and FIPS_mode_set() functions in Python (ssl) ,我还提交了 Python 3.4 的补丁(其中公开了 ssl 模块),但它基于以下参数被拒绝(其中1 st 2是相关的):
您可以将它应用于 Python 3.6 (我认为它不会起作用 OOTB ,因为行号最有可能发生变化),并且(显然)你和#39;我必须从源代码构建 Python 。
底线:
<强> @ EDIT0 强>:
它只是让我感到震惊,您在[SO]: Not able to call FIPS_mode_set() of libcrypto.so with Python ctypes [duplicate]遇到的行为也可能与错误 libcrypto 正在加载有关(请查看openssl version
从头开始测试w
非 FIPS 的 OpenSSL 仍将导出2个函数,但它们都只返回0.
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049320993]> ./code.py 1 Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux OPENSSL_VERSION: OpenSSL 1.0.2g 1 Mar 2016 FIPS_mode(): 0 FIPS_mode_set(1): 0 FIPS_mode(): 0 SHA1: da39a3ee5e6b4b0d3255bfef95601890afd80709 MD5: d41d8cd98f00b204e9800998ecf8427e
因此,请确保通过指定 LD_LIBRARY_PATH 来加载正确的库! (还有其他方法,但这是最简单的方法)。