在需要对加密操作进行合规性控制的场景中,FIPS 140-2(或 FIPS 140-3)是一个重要的标准。本文介绍如何在 OpenSSL 中启用和配置 FIPS 模式。

什么是 FIPS 140-2?

FIPS 140-2 是美国国家标准与技术研究院(NIST)发布的密码学模块安全要求标准。它定义了四个安全等级(Level 1-4),要求密码学实现经过严格测试和验证。

关键点:

  • 强制要求在政府机构和受监管行业使用
  • OpenSSL 通过 FIPS 模块(OpenSSL-FIPS)提供支持
  • FIPS 模式开启后,仅允许使用经认证的加密算法

环境检查

首先检查当前 OpenSSL 版本:

1
openssl version -a

注意输出中的 FIPS 标记。如果显示 fips-mode 相关信息,说明已支持 FIPS。

安装 OpenSSL FIPS 模块

方法一:使用系统包管理器(推荐)

Ubuntu/Debian:

1
2
sudo apt update
sudo apt install openssl-fips

RHEL/CentOS:

1
sudo yum install openssl-fips

方法二:从源码编译

1
2
3
4
5
6
7
8
9
# 下载 OpenSSL FIPS 模块源码(以 2.0.x 为例)
wget https://github.com/openssl/openssl-fips/releases/download/fips-2.0.16/openssl-fips-2.0.16.tar.gz
tar -xzf openssl-fips-2.0.16.tar.gz
cd openssl-fips-2.0.16

# 编译安装
./config
make
sudo make install

编译安装后需要重新编译 OpenSSL 以链接 FIPS 模块。

启用 FIPS 模式

方法一:环境变量

1
2
3
4
5
# 启用 FIPS 模式
export OPENSSL_FORCE_FIPS_MODE=1

# 验证
openssl md5 test.txt  # 此命令在 FIPS 模式下会失败

注意: MD5 不在 FIPS 允许的哈希算法列表中,此命令应返回错误。

方法二:配置文件

编辑 /etc/ssl/openssl.cnf(路径因系统而异):

1
2
3
4
5
6
7
8
# 在 [default_params] 或 [openssl_init] 部分添加
openssl_conf = openssl_init

[openssl_init]
fips_mode = yes

[ algorithmic_default ]
default_properties = fips=yes

方法三:程序级启用

在代码中使用:

1
2
3
4
#include <openssl/crypto.h>

// 启用 FIPS 模式
FIPS_mode_set(1);

验证 FIPS 模式

验证 FIPS 模式是否成功启用:

1
2
# 检查 FIPS 模式状态(需要编写简单测试程序或使用 OpenSSL C API)
openssl version -a | grep -i fips

另一种验证方式:

1
2
# 在 FIPS 模式下测试允许的算法
echo "test" | openssl dgst -sha256

此命令在 FIPS 模式下应正常工作。

FIPS 允许的哈希算法:

  • SHA-1, SHA-224, SHA-256, SHA-384, SHA-512
  • SHA-3 系列

FIPS 不允许的算法:

  • MD5, MD4, MD2
  • DES, 3DES(仅允许特定模式)
  • RC4

FIPS 模式下的 TLS 配置

在 Nginx 中配置 FIPS 兼容的密码套件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
server {
    listen 443 ssl;
    server_name example.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    # FIPS 兼容的密码套件
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers on;
    
    # 仅启用 TLS 1.2 及以上
    ssl_protocols TLSv1.2 TLSv1.3;
}

验证 Nginx 配置的密码套件是否符合 FIPS 要求:

1
openssl s_client -connect example.com:443 -cipher 'ECDHE-ECDSA-AES256-GCM-SHA384' </dev/null

常见问题

1. FIPS 模式导致兼容性问题

问题: 启用 FIPS 后,某些旧客户端无法连接。

解决:

  • 确保服务器同时支持 FIPS 和非 FIPS 客户端(使用合适的密码套件优先级)
  • 对于必须支持旧客户端的场景,可考虑双协议栈

2. 自签名证书在 FIPS 模式下无法使用

问题: 使用 MD5 签名的自签名证书无法通过验证。

解决: 使用 FIPS 允许的算法重新生成证书:

1
2
3
# 使用 SHA-256 签名(符合 FIPS 要求)
openssl req -new -x509 -days 365 -sha256 -newkey rsa:2048 \
    -keyout key.pem -out cert.pem

3. FIPS 模块加载失败

问题: 提示 “FIPS module not loaded”。

解决:

  1. 确认 FIPS 模块已正确安装
  2. 检查环境变量 OPENSSL_FIPS 指向正确的模块路径
  3. 查看系统日志中的详细错误信息

限制与注意事项

  1. 性能影响: FIPS 模块的自我检查会带来轻微性能开销
  2. 算法限制: 某些常用算法(如 RC4、MD5)将不可用
  3. 合规验证: 实际合规性需要通过官方认证测试,仅启用 FIPS 模式不足以声称符合 FIPS 标准
  4. 版本要求: 使用较新的 OpenSSL 版本(1.1.1 或 3.x)以获得完整的 FIPS 支持

总结

通过正确配置 OpenSSL FIPS 模式,可以在需要合规的场景中使用经过认证的加密实现。启用 FIPS 模式后,系统会自动限制使用非认证算法,这有助于满足政府机构和受监管行业的密码学安全要求。


参考来源: