Hus*_*bar 3 python ssl ctypes openssl python-3.x
我有一个 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(从源代码构建)
蟒蛇:3.6
操作系统:Ubuntu 16.04 LTS
如果需要任何其他详细信息,请告诉我。
谢谢!
我已经使用常规标志构建了OpenSSL-fips模块(例如:no-asm、shared、禁用了一些古老的密码):
Run Code Online (Sandbox Code Playgroud)[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049320993]> ~/sopr.sh *** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages *** [064bit-prompt]> 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
并开始玩弄它:
Run Code Online (Sandbox Code Playgroud)[064bit-prompt]> 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来完成的(同样的行为也可以通过在构建OpenSSL时设置 env var 来实现,这会在openssl 中设置rpath 可执行文件,但我忘记了,我不想再次构建它):
Run Code Online (Sandbox Code Playgroud)[064bit-prompt]> LD_LIBRARY_PATH=ssl/build/lib ssl/build/bin/openssl version OpenSSL 1.0.2h-fips 3 May 2016
现在,设置成功,让我们深入研究OPENSSL_FIPS 环境变量:
Run Code Online (Sandbox Code Playgroud)[064bit-prompt]> LD_LIBRARY_PATH=ssl/build/lib ssl/build/bin/openssl md5 ./code.py MD5(./code.py)= d41d8cd98f00b204e9800998ecf8427e [064bit-prompt]> LD_LIBRARY_PATH=ssl/build/lib ssl/build/bin/openssl sha1 ./code.py SHA1(./code.py)= da39a3ee5e6b4b0d3255bfef95601890afd80709 [064bit-prompt]> OPENSSL_FIPS=1 LD_LIBRARY_PATH=ssl/build/lib ssl/build/bin/openssl sha1 ./code.py SHA1(./code.py)= da39a3ee5e6b4b0d3255bfef95601890afd80709 [064bit-prompt]> 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 的环境变量(当FIPS模式打开时,它的使用是不允许的)。
注意事项:
由于OPENSSL_FIPS env var是在openssl可执行级别处理的,会被绕过(因为会直接使用libcrypto),所以对目前的情况没有用,所以我们必须更深入。这些是在加载的libcrypto实例中控制FIPS模式的函数:
它们将用于读/写FIPS模式。为了测试是否真的设置了FIPS模式,将使用md5哈希(来自上面的示例)。
代码.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()))
Run Code Online (Sandbox Code Playgroud)
注意事项:
import hashlib语句位于后设置FIPS模式(而不是在文件开头,因为它应该是),因为hashlib做一些缓存在导入时,所以它抓住了FIPS在进口时间值,并且不介意之后会发生变化输出:
Run Code Online (Sandbox Code Playgroud)[064bit-prompt]> 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 [064bit-prompt]> 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的)上,也可以通过编辑一些条目(在/proc 下?)来设置FIPS模式(系统全局),但我不记得了。
一个更好的方法将是公开的Python为2个函数的包装。
检查[Python.Bugs]: FIPS_mode() 和 FIPS_mode_set() 函数在 Python (ssl) 中,我还提交了Python 3.4的补丁(它们由ssl模块公开),但基于以下原因被拒绝参数(其中 1 st 2 是相关的):
您可以将其应用于Python 3.6(我认为它不会在OOTB 中工作,因为行号很可能已更改),并且(显然)您必须从源代码构建Python。
底线:
它只是让我感到震惊,您在[SO]上遇到的行为:无法使用 Python ctypes [重复] 调用 libcrypto.so 的 FIPS_mode_set()也可能与加载错误的libcrypto有关(检查openssl version测试 w/ wo LD_LIBRARY_PATH从一开始)。
非FIPS能够OpenSSL的将仍然出口2层的功能,但他们都只是简单地返回0。
Run Code Online (Sandbox Code Playgroud)[064bit-prompt]> ./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来加载正确的库!(还有其他方法,但这是最直接的一种)。
| 归档时间: |
|
| 查看次数: |
8053 次 |
| 最近记录: |