2 FIPS 模式
2.1 背景
OpenSSL 可以构建为提供经 FIPS 140-2 认证的加密服务。经过认证的不是 OpenSSL 应用程序本身,而是称为 OpenSSL FIPS 对象模块的特殊软件组件。但是,应用程序不直接使用该对象模块,而是通过 OpenSSL 库的常规 API 使用。
crypto 应用程序支持在 FIPS 模式下使用 OpenSSL。在这种情况下,只有对象模块提供的经过认证的算法可用,其他通常在 OpenSSL 中可用(如 md5)或在 Erlang 代码中实现(如 SRP)的算法将被禁用。
2.2 启用 FIPS 模式
-
构建或安装 FIPS 对象模块和支持 FIPS 的 OpenSSL 库。
警告从源代码构建一个可用的 OpenSSL FIPS 对象模块和库非常容易。但是,如果未严格遵循安全策略中的众多限制,则不符合 FIPS 140-2 认证。
-
配置和构建支持 FIPS 的 Erlang/OTP
$ cd $ERL_TOP $ ./otp_build configure --enable-fips ... checking for FIPS_mode_set... yes ... $ make
如果FIPS_mode_set返回no,则 OpenSSL 库不支持 FIPS,crypto 也不支持 FIPS 模式。
-
在加载 crypto 模块之前,将 crypto 应用程序的fips_mode配置设置设置为true。
最佳位置是发行版中的sys.config系统配置文件。
- 照常启动和使用 crypto 应用程序。但是,请注意避免使用未经 FIPS 认证的算法,它们都会抛出not_supported异常。
不支持在已运行 crypto 的节点上进入和退出 FIPS 模式。原因是 OpenSSL 旨在防止请求 FIPS 模式的应用程序最终意外地以非 FIPS 模式运行。如果进入 FIPS 模式失败(例如,未找到对象模块或对象模块已损坏),则随后对 OpenSSL API 的任何使用都会终止仿真器。
因此,必须在受任何并发运行的 crypto 操作保护的临界区中执行动态 FIPS 模式更改。此外,如果发生故障,必须从 Erlang 或 nif 代码中禁用所有 crypto 调用。这将为这个不太重要的功能投入太多精力。
2.3 与常规构建的兼容性问题
无论是否支持 FIPS,crypto 应用程序的 Erlang API 都是相同的。但是,nif 代码在内部使用不同的 OpenSSL API。
这意味着从流式加密函数(hash_(init|update|final)、hmac_(init|update|final) 和stream_(init|encrypt|decrypt))返回的上下文(不透明类型)与在使用 FIPS 支持编译 crypto 时与常规构建不同且不兼容。
2.4 常见注意事项
在 FIPS 模式下,未经认证的算法将被禁用。这可能会导致依赖 crypto 的应用程序出现一些意外问题。
不要尝试使用丢失算法的替代实现来解决这些问题!如果应用程序仅在每次加密操作中都使用经过 FIPS 140-2 认证的加密模块,则它才能宣称使用该模块。
密钥大小限制
尽管 FIPS 模式支持公钥算法,但它们只能与安全密钥大小一起使用。安全策略要求以下最小值
- RSA
- 1024 位
- DSS
- 1024 位
- EC 算法
- 160 位
椭圆曲线限制
Erlang API 允许使用任意曲线参数,但在 FIPS 模式下,仅允许安全策略允许的参数。
避免使用 md5 进行哈希
Md5 作为哈希函数很受欢迎,但其安全性不足以获得认证。尽可能尝试使用 sha 代替。
对于特殊情况,非加密用例,可以考虑切换到erlang:md5/1。
证书和加密密钥
由于 FIPS 模式下不可用 md5,因此只能使用使用 sha 哈希签名的证书。验证整个证书链时,所有证书(包括根 CA 的证书)必须符合此规则。
由于对 md5 和 des 算法的类似依赖,大多数 PEM 格式的加密私钥也不起作用。但是,PBES2 加密方案允许使用更强大的经过 FIPS 认证的算法,这是一种可行的替代方案。
SNMP v3 限制
在 FIPS 模式下,只能使用usmHMACSHAAuthProtocol 和usmAesCfb128Protocol 进行身份验证和隐私保护。但是,snmp 应用程序不会以任何方式限制选择禁用的协议,使用它们会导致运行时崩溃。
需要 TLS 1.2
所有早于 TLS 1.2 的 SSL 和 TLS 版本都在握手过程中将 md5 和 sha1 哈希组合用于各种目的
- 验证握手消息的完整性。
- 在提供非匿名 PFS(完美前向保密)的密码套件中交换 DH 参数。
- 在 PRF(伪随机函数)中生成不使用 PFS 的密码套件中的密钥材料。
OpenSSL 在 FIPS 模式下处理这些特殊情况,但是 Erlang crypto 和 ssl 应用程序没有为此做好准备,因此您在 FIPS 模式下只能使用 TLS 1.2。
另一方面,值得一提的是,至少所有依赖于未经认证的算法的密码套件在 FIPS 模式下都会自动被禁用。
使用弱(md5)摘要的证书也可能导致 TLS 出现问题。虽然 TLS 1.2 有一个扩展用于指定接受哪种类型的签名,并且在 FIPS 模式下,ssl 应用程序将正确使用它,但大多数 TLS 实现会忽略此扩展,并简单地发送其配置的任何证书。