16.8.OpenSSL

OpenSSL 是一款加密工具包,实现在网络协议中使用的安全套接字层(SSL)和传输层安全性(TLS)协议,并提供许多加密功能。

openssl 程序是一款命令行工具,能通过 shell 使用 OpenSSL 加密库的各种加密功能。它可以用于:

  • 创建和管理私钥、公钥和参数

  • 公钥加密操作

  • 创建 X.509 证书、证书签名请求(CSR)和证书撤销列表(CRL)

  • 计算消息摘要

  • 使用密码进行加密和解密

  • SSL/TLS 客户端和服务器测试

  • 处理 S/MIME 签名或加密邮件

  • 时间戳请求、生成和验证

  • 基准测试加密例程

有关 OpenSSL 的更多信息,请阅读免费的 OpenSSL Cookbook

16.8.1. 生成证书

OpenSSL 支持生成证书,无论是通过 CA 验证的证书,还是供自用的证书。

运行命令 openssl(1) 来生成一个有效的证书,向 CA 请求证书。此命令将在当前目录创建两个文件。证书请求文件 req.pem 可以发送给一个 CA,该 CA 会验证输入的凭据,签名请求并返回签名后的证书。第二个文件 cert.key 是证书的私钥,应存放在安全的地方。如果此文件被他人获取,它可以用于冒充用户或服务器。

执行以下命令来生成证书:

# openssl req -new -nodes -out req.pem -keyout cert.key -sha3-512 -newkey rsa:4096

输出类似如下:

Generating a RSA private key
..................................................................................................................................+++++
......................................+++++
writing new private key to 'cert.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:ES
State or Province Name (full name) [Some-State]:Valencian Community
Locality Name (eg, city) []:Valencia
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:Systems Administrator
Common Name (e.g. server FQDN or YOUR name) []:localhost.example.org
Email Address []:user@FreeBSD.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456789
An optional company name []:Another name

或者,如果不需要 CA 签名,则可以创建一个自签名证书。这样会在当前目录创建两个新文件:一个是私钥文件 cert.key,另一个是证书文件 cert.crt。这些文件应放置在一个目录中,最好是在 /etc/ssl/ 下,该目录仅对 root 用户可读。将文件的权限设置为 0700,可以使用 chmod 设置。

执行以下命令来生成证书:

# openssl req -new -x509 -days 365 -sha3-512 -keyout /etc/ssl/private/cert.key -out /etc/ssl/certs/cert.crt

输出类似如下:

Generating a RSA private key
........................................+++++
...........+++++
writing new private key to '/etc/ssl/private/cert.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:ES
State or Province Name (full name) [Some-State]:Valencian Community
Locality Name (eg, city) []:Valencia
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:Systems Administrator
Common Name (e.g. server FQDN or YOUR name) []:localhost.example.org
Email Address []:user@FreeBSD.org

16.8.2. 配置 FIPS 提供程序

在 FreeBSD 14 及更高版本中,OpenSSL 3 被引入到基本系统,并且引入了提供程序模块的概念。除了库中内置的默认提供程序模块外,legacy 模块实现了现已过时的、可选的加密算法,而 fips 模块则将 OpenSSL 的实现限制为符合 FIPS 标准集的加密算法。OpenSSL 中这一部分得到了 特别关注,包括 相关安全问题的列表,并且定期接受 FIPS 140 验证过程。也可以查阅 FIPS 验证版本的列表,以确保用户在使用 OpenSSL 时符合 FIPS 标准。

重要的是, fips_module(7) 受到额外的安全措施保护,禁止在未通过完整性检查的情况下使用该模块。此检查可以由本地系统管理员进行设置,允许每个 OpenSSL 3 的用户加载该模块。如果配置不正确,FIPS 模块将按以下方式失败:

# echo test | openssl aes-128-cbc -a -provider fips -pbkdf2

输出应类似如下:

aes-128-cbc: unable to load provider fips
Hint: use -provider-path option or OPENSSL_MODULES environment variable.
00206124D94D0000:error:1C8000D5:Provider routines:SELF_TEST_post:missing config data:crypto/openssl/providers/fips/self_test.c:275:
00206124D94D0000:error:1C8000E0:Provider routines:ossl_set_error_state:fips module entering error state:crypto/openssl/providers/fips/self_test.c:373:
00206124D94D0000:error:1C8000D8:Provider routines:OSSL_provider_init_int:self test post failure:crypto/openssl/providers/fips/fipsprov.c:707:
00206124D94D0000:error:078C0105:common libcrypto routines:provider_init:init fail:crypto/openssl/crypto/provider_core.c:932:name=fips

可以通过在 /etc/ssl/fipsmodule.cnf 中创建文件来配置检查,然后在 OpenSSL 的主配置文件 /etc/ssl/openssl.cnf 中引用该文件。OpenSSL 提供了 openssl-fipsinstall(1) 工具来帮助完成此过程,可以按如下方式使用:

# openssl fipsinstall -module /usr/lib/ossl-modules/fips.so -out /etc/ssl/fipsmodule.cnf

输出应类似如下:

INSTALL PASSED

然后应该修改 /etc/ssl/openssl.cnf 文件,以便:

  • 包含上述生成的 /etc/ssl/fipsmodule.cnf 文件,

  • 暴露 FIPS 模块以供可能使用,

  • 并显式激活默认模块。

[...]
# 对于 FIPS
# 可选地包含一个由 OpenSSL fipsinstall 应用程序生成的文件。该文件包含 OpenSSL fips 提供者所需的配置数据。
# 它包含一个命名的部分,例如 [fips_sect],该部分在下面的 [provider_sect] 中被引用。
# 有关更多信息,请参阅 OpenSSL 安全策略。
.include /etc/ssl/fipsmodule.cnf

[...]

# 要加载的提供者列表
[provider_sect]
default = default_sect
# fips 部分名称应与包含的 fipsmodule.cnf 中的部分名称匹配。
fips = fips_sect

# 如果没有显式激活提供者,则默认提供者会被隐式激活。
# 有关更多细节,请参见 man 7 OSSL_PROVIDER-default。
#
# 如果显式添加一个部分来激活任何其他提供者,你很可能需要显式激活默认提供者,否则它
# 将在 openssl 中不可用。结果,依赖于 OpenSSL 的应用程序可能无法正常工作,这可能会导致
# 系统出现重大问题,包括无法远程访问系统。
[default_sect]
activate = 1

完成此操作后,应该可以确认 FIPS 模块有效并且可以正常工作:

# echo test | openssl aes-128-cbc -a -provider fips -pbkdf2

输出应类似如下:

enter AES-128-CBC encryption password:
Verifying - enter AES-128-CBC encryption password:
U2FsdGVkX18idooW6e3LqWeeiKP76kufcOUClh57j8U=

每当修改 FIPS 模块时,例如在进行系统更新或应用 OpenSSL 相关的安全修复后,都必须重复此过程。

最后更新于