查看源代码 FIPS 模式

本章节介绍 crypto 应用程序中的 FIPS 模式支持。

背景

可以构建 OpenSSL 以提供 FIPS 140-2 验证的加密服务。验证的不是 OpenSSL 应用程序,而是一个名为 OpenSSL FIPS 对象模块的特殊软件组件。但是,应用程序不是直接使用此对象模块,而是通过 OpenSSL 库的常规 API 使用。

crypto 应用程序支持在 FIPS 模式下使用 OpenSSL。在这种情况下,只能访问对象模块提供的已验证算法,其他通常在 OpenSSL 中可用(如 md5)或在 Erlang 代码中实现(如 SRP)的算法将被禁用。

启用 FIPS 模式

  1. 构建或安装 FIPS 对象模块和启用 FIPS 的 OpenSSL 库。

您应该阅读并严格遵循 安全策略用户指南 中的说明。

警告

从源代码构建一个可用的 OpenSSL FIPS 对象模块和库非常容易。但是,如果未正确遵循安全策略中的许多限制,它符合 FIPS 140-2 验证的要求。

  1. 配置并构建带有 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 模式。

  1. 加载 crypto 模块之前,将 crypto 应用程序的 fips_mode 配置设置设置为 true

最好的位置是在发行版本的 sys.config 系统配置文件中。

  1. 像往常一样启动和使用 crypto 应用程序。但是请注意避免使用未经 FIPS 验证的算法,它们都会抛出异常 not_supported

不支持在已运行 crypto 的节点上进入和退出 FIPS 模式。原因是 OpenSSL 的设计目的是防止请求 FIPS 模式的应用程序意外地在非 FIPS 模式下运行。如果进入 FIPS 模式失败(例如,未找到对象模块或对象模块已损坏),则任何后续的 OpenSSL API 使用都将终止模拟器。

因此,必须在受任何并发运行的 crypto 操作保护的临界区中执行即时 FIPS 模式更改。此外,如果发生故障,则必须从 Erlang 或 nif 代码禁用所有 crypto 调用。这对于这个不太重要的功能来说投入太多精力。

与常规构建的不兼容性

无论是否使用 FIPS 支持进行构建,crypto 应用程序的 Erlang API 都是相同的。但是,nif 代码在内部使用不同的 OpenSSL API。

这意味着从流式加密函数(hash_(init|update|final)hmac_(init|update|final)stream_(init|encrypt|decrypt))返回的上下文(不透明类型)是不同的,并且在编译带有 FIPS 支持的 crypto 时与常规构建不兼容。

常见注意事项

在 FIPS 模式下,未验证的算法将被禁用。这可能会在依赖 crypto 的应用程序中引起一些意外问题。

警告

不要尝试通过使用缺少算法的替代实现来解决这些问题!如果应用程序完全使用 FIPS 140-2 验证的加密模块进行每次加密操作,则该应用程序只能声称正在使用该模块。

密钥大小的限制

尽管在 FIPS 模式下支持公钥算法,但它们只能与安全的密钥大小一起使用。安全策略要求以下最小值

  • RSA - 1024 位

  • DSS - 1024 位

  • EC 算法 - 160 位

椭圆曲线的限制

Erlang API 允许使用任意曲线参数,但在 FIPS 模式下,只能使用安全策略允许的参数。

避免使用 md5 进行哈希

Md5 是一种常用的哈希函数,但其安全性不足以进行验证。请尽可能尝试使用 sha 代替。

对于特殊的非加密用例,可以考虑切换到 erlang:md5/1

证书和加密密钥

由于 md5 在 FIPS 模式下不可用,因此只能使用使用 sha 哈希签名的证书。在验证整个证书链时,所有证书(包括根 CA 的证书)都必须符合此规则。

由于对 md5 和 des 算法的类似依赖,大多数 PEM 格式的加密私钥也无法使用。但是,PBES2 加密方案允许使用更强大的 FIPS 验证算法,这是一个可行的替代方案。

SNMP v3 限制

在 FIPS 模式下,只能分别使用 usmHMACSHAAuthProtocolusmAesCfb128Protocol 进行身份验证和隐私保护。但是,snmp 应用程序不会以任何方式限制选择禁用的协议,使用它们会导致运行时崩溃。

需要 TLS 1.2

TLS 1.2 之前的所有 SSL 和 TLS 版本在握手中都会将 md5 和 sha1 哈希组合用于各种目的

  • 验证握手消息的完整性。
  • 在提供非匿名 PFS(完全前向保密)的密码套件中交换 DH 参数。
  • 在不使用 PFS 的密码套件中使用 PRF(伪随机函数)来生成密钥材料。

OpenSSL 在 FIPS 模式下处理这些极端情况,但是 Erlang crypto 和 ssl 应用程序没有为此做好准备,因此在 FIPS 模式下您只能使用 TLS 1.2。

另一方面,值得一提的是,至少所有依赖于未经验证的算法的密码套件都会在 FIPS 模式下自动禁用。

注意

使用弱(md5)摘要的证书也可能在 TLS 中引起问题。尽管 TLS 1.2 有一个扩展来指定接受哪种类型的签名,并且在 FIPS 模式下 ssl 应用程序将正确使用它,但是大多数 TLS 实现都忽略此扩展,而只是发送它们配置的任何证书。