OpenSSL

来自 ArchWiki
(重定向自 Openssl)

OpenSSL 是 SSL 和 TLS 协议的开源实现,旨在尽可能灵活。它在多种平台上受支持,包括 BSD、Linux、OpenVMS、Solaris 和 Windows。

安装

openssl 在 Arch Linux 上默认安装(作为 coreutils 的依赖项)。

有各种 OpenSSL 库绑定可供开发者使用

配置

在 Arch Linux 上,OPENSSLDIR/etc/ssl

OpenSSL 配置文件通常放在 /etc/ssl/openssl.cnf,起初可能看起来很复杂。请记住,变量可以在赋值中展开,很像 shell 脚本的工作方式。有关配置文件格式的详尽解释,请参阅 config(5ssl)

req 节

本文或本节是与 #生成证书签名请求 合并的候选对象。

注意: 相同主题。(在 Talk:OpenSSL#Plan 中讨论)

与生成密钥、请求和自签名证书相关的设置。

req 节负责 DN 提示。一个普遍的误解是常用名称 (CN) 提示,它暗示应该将用户的真实姓名作为值。终端用户证书需要将机器主机名作为 CN,而 CA应具有有效的 TLD,这样就不会有可能在认证的终端用户的 CN 和 CA 证书的可能组合之间,存在被某些软件误解为意味着终端用户证书是自签名的匹配项。一些 CA 证书甚至没有 CN,例如 Equifax

$ openssl x509 -subject -noout < /etc/ssl/certs/Equifax_Secure_CA.pem
subject= /C=US/O=Equifax/OU=Equifax Secure Certificate Authority

用法

本节假设您已阅读 传输层安全#获取证书

生成 Curve25519 私钥

$ openssl genpkey -algorithm x25519 -out filename

生成 ECDSA 私钥

$ openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out filename

生成 RSA 私钥

使用 openssl-genpkey(1ssl),根据 openssl(1ssl),它取代了 genrsa

$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:keysize -out filename

如果需要加密密钥,请使用 -aes-256-cbc 选项。

生成证书签名请求

使用 openssl-req(1ssl)

$ openssl req -new -sha256 -key private_key -out filename

显示证书签名请求

证书签名请求以编码格式存储。要以人类可读的格式查看请求

$ openssl req -noout -text -in filename

生成自签名证书

本文或本节需要扩充。

原因: 这会为(根)证书颁发机构生成证书,您正在充当该机构。大多数 Web 浏览器似乎不接受 CA 证书,认为有必要请求另一个证书并使用 CA 证书和 CA 密钥对其进行签名。 此论坛帖子 中的“生成由自己的 CA 颁发的证书”过程似乎满足了浏览器的要求。(在 Talk:OpenSSL 中讨论)
$ openssl req -key private_key -x509 -new -days days -out filename

在单个命令中生成包含私钥的自签名证书

您可以将上面的 OpenSSL 命令组合成一个命令,这在某些情况下可能很方便。

ECDSA

$ openssl req -x509 -newkey ec -pkeyopt 'ec_paramgen_curve:P-256' -days days -keyout key_filename -out cert_filename

RSA

$ openssl req -x509 -newkey rsa:4096 -days days -keyout key_filename -out cert_filename

使用 CA 证书签署证书签名请求

$ openssl x509 -req -in cert_req_filename -days days -CA CA_cert -CAkey CA_cert_private_key -CAserial CA_cert_serial_file -out cert_out

生成 Diffie–Hellman 参数

有关更多信息,请参阅 Diffie–Hellman 密钥交换

当前的 最佳实践 是使用来自 RFC:7919 的标准 DH 组之一,例如 ffdhe2048

或者,您可以生成自己的随机组

$ openssl dhparam -out filename 2048
提示: 为了加速生成,尤其是在非高端硬件上,添加 -dsaparam 选项 [1]

显示证书信息

$ openssl x509 -text -in cert_filename

显示证书指纹

$ openssl x509 -noout -in cert_filename -fingerprint -digest

-digest 是可选的,可以是 -md5-sha1-sha256-sha512 之一。有关摘要未指定时的情况,请参阅 x509(1ssl) § 输入、输出和通用目的选项 中的“-digest”。

转换证书格式

使用 openssl x509 将证书从二进制 (DER) 格式转换为 PEM 格式(带有 BEGIN CERTIFICATE 标头的文本格式):

$ openssl x509 -inform DER -in myCA.crt -out myCA_pem.crt

使用第三方提供程序

OpenSSL 3 引入了提供程序作为 OpenSSL 可插拔性的新概念。可以使用未包含在 OpenSSL 中的算法,而无需重新编译它。例如,要测试 NIST 后量子密码学 算法,您可以安装 Open Quantum Safe 提供程序 oqsproviderAUR。例如,您可以使用 ML-DSA(以前的 CRYSTALS-Dilithium)的变体之一生成量子安全自签名证书和私钥

$ openssl req -provider default -provider oqsprovider -x509 -newkey mldsa65 -days days -keyout key -out cert

故障排除

解密时出现 “bad decrypt” 错误

OpenSSL 1.1.0 将 dgst 和 enc 命令的默认摘要算法从 MD5 更改为 SHA256。 [2]

因此,如果文件是使用 OpenSSL 1.0.2 或更旧版本加密的,则尝试使用最新版本解密它可能会导致类似如下的错误

error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:crypto/evp/evp_enc.c:540

提供 -md md5 选项应该可以解决问题

$ openssl enc -d -md md5 -in encrypted -out decrypted

Python 3.10 和 “ca md too weak” 错误

在 Python 3.10 中,默认情况下有一个硬编码的允许的 OpenSSL 密码列表。一些安全性较低的密码,如 MD5,已在 ssl 模块级别禁用,忽略了 OpenSSL 的系统级配置。有时会导致旧证书出现奇怪的错误,有时甚至在建立 https 连接时也会出现,例如

requests.exceptions.SSLError: HTTPSConnectionPool(host='a.kind.of.example.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError(398, '[SSL: CA_MD_TOO_WEAK] ca md too weak (_ssl.c:3862)')))

要使 Python 遵循系统配置,您可能需要重建它,并将 --with-ssl-default-suites=openssl 参数添加到 ./configure。该问题也已报告为 FS#73549

设置密码 XXX 时出错

如果您尝试使用“已弃用”的密码,您将收到此类错误

$ openssl bf -d -in cipher_file -K passphrase
Error setting cipher BF-CBC
4087A97A8A7F0000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:341:Global default library context, Algorithm (BF-CBC : 12)

自 OpenSSL 3.0 以来,加密算法通过“提供程序”提供。最旧或最少使用的算法属于 legacy 提供程序。 [3]

如果您需要使用已弃用的算法,如 DES、RC4、Blowfish 等,您必须在命令行中添加选项 -provider legacy

这是一个用于解码 Blowfish 密码的完整示例。

$ openssl bf -d -in cipher_file -provider legacy -provider default -K passphrase

参见