跳转至内容

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 部分

本文或本节是候选合并到 #生成证书签名请求 (CSR)

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

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

req 部分负责 DN 提示。一个普遍的误解是“通用名称”(CN) 提示,它暗示应该以用户的真实姓名作为值。终端用户证书需要以计算机主机名作为 CN,而 CA 则不应具有有效的 TLD,这样就不可能出现证书颁发机构 (CA) 证书中的 CN 与终端用户证书中的 CN 组合匹配,而被某些软件误解为终端用户证书是自签名的。一些 CA 证书甚至没有 CN,例如

$ openssl x509 -subject -noout -in /etc/ssl/certs/AC_RAIZ_FNMT-RCM.pem
subject=C=ES, O=FNMT-RCM, OU=AC RAIZ FNMT-RCM

用法

本节假设您已阅读 Transport Layer Security#获取证书

生成 Ed25519 私钥

$ openssl genpkey -algorithm ed25519 -out filename

生成 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) Supersedes 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

生成自签名证书

本文章或章节需要扩充。

原因: 这将为(根)证书颁发机构生成证书,而您扮演的是 CA。大多数 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 参数

DH,Diffie–Hellman,密钥交换是一种协议,用于在双方之间协商共享密钥,而协商本身通过公共网络安全地进行。(维基百科文章)。生成的共享密钥可用于通过公共网络交换数据的秘密通信。DH 协议通过一种方式建立双方对最终共享密钥的贡献,即使有被动监听者也无法重建结果共享密钥。在公共网络上实现共享密钥的另一种常见方法是,一方使用长期非对称密钥加密该密钥并将其发送给密钥所有者(如 RSA 密钥交换中的情况)[1]。因此,其他算法随后用于加密本身[2]。为了设定协商过程中将提出的要求,双方可以预先定义一组要求。这些要求就是 Diffie–Hellman 参数。定义这些参数的常用方法是使用数学函数。常用的函数有两种:模素数的指数运算(形成有限域 Diffie-Hellman,或 FFDH)和椭圆曲线上的点乘(形成椭圆曲线 Diffie-Hellman,或 ECDH)。

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

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

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

显示证书信息

$ openssl x509 -text -in cert_filename

要查看服务器的证书,请使用 openssl-s_client(1ssl)

$ openssl s_client -showcerts -connect hostname:port </dev/null | openssl x509 -text

显示证书指纹

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

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

转换证书格式

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

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

使用第三方提供者

OpenSSL 3 引入了提供者 (providers) 的新概念,用于 OpenSSL 的插件化。可以在不重新编译 OpenSSL 的情况下使用 OpenSSL 未包含的算法。

oqsprovider

要测试 NIST 后量子密码学算法,可以安装 Open Quantum Safe 提供者 oqsproviderAUR。例如,您可以使用 ML-DSA(以前称为 CRYSTALS-Dilithium)的某个变体来生成一个抗量子的自签名证书及私钥 ML-DSA

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

tpm2-openssl

要将 ECDSA 和 RSA 私钥存储在 TPM 中,请安装 tpm2-openssl。有关如何使用它的文档,请参阅其 README

故障排除

解密时出现 "bad decrypt"

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

因此,如果一个文件是用 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 遵循系统配置,您可能需要重新编译它,并在 ./configure 中添加 --with-ssl-default-suites=openssl 参数。此问题也已报告为 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 提供者。[5]

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

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

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

参见