2、OpenSSL工具入门:安装、配置与常用命令
说实话,搞证书这行,OpenSSL 就是你的瑞士军刀。我入行那会儿,第一个任务就是帮客户生成一套测试证书。那时候啥也不懂,拿着 OpenSSL 的命令一顿乱敲,结果生成的证书浏览器死活不认。后来才发现,是配置文件里一个参数写错了。嗯,从那以后我就养成了一个习惯——先把工具本身摸透,再动手干活。
这一节,我们就来把 OpenSSL 的安装、配置和几个最常用的命令过一遍。别小看这些基础操作,后面所有证书的生成、转换、验证,全得靠它们。
2.1 安装与配置
OpenSSL 的安装其实不复杂,但不同系统下还是有些小区别。我个人的习惯是,能用包管理器装就用包管理器,省心。
Linux 环境(以 Ubuntu/CentOS 为例)
# Ubuntu / Debian
sudo apt update
sudo apt install openssl
# CentOS / RHEL / Rocky Linux
sudo yum install openssl
# 验证安装
openssl version
装完之后,跑一下 openssl version,能看到类似 OpenSSL 1.1.1k 25 Mar 2021 的输出,就说明装好了。这里要注意,版本号很重要。我曾经遇到过因为 OpenSSL 版本太老,导致 TLS 1.3 握手失败的案例。所以,建议尽量用 1.1.1 以上版本。
macOS 环境
macOS 自带的 OpenSSL 版本通常比较旧。我建议用 Homebrew 装一个新的:
brew install openssl
# 注意:Homebrew 安装的 openssl 默认不会覆盖系统自带的
# 需要手动配置 PATH,或者直接用 brew 的路径调用
echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
Windows 环境
Windows 下稍微麻烦点。我一般去 Win32 OpenSSL 页面 下载安装包。装完之后,记得把 OpenSSL 的 bin 目录(比如 C:\Program Files\OpenSSL-Win64\bin)加到系统环境变量 Path 里。不然每次都要输全路径,太折腾了。
openssl version -a。这个命令会显示编译参数、安装路径等信息。特别是 OPENSSLDIR 这个路径,它指向 OpenSSL 的配置文件(openssl.cnf)所在位置。后面很多操作都要用到这个文件。
2.2 配置文件(openssl.cnf)初探
OpenSSL 的配置文件,说白了就是它的“大脑”。里面定义了证书请求的默认参数、CA 的默认策略、扩展属性等等。我刚开始用的时候,觉得这东西太复杂,直接忽略。结果生成的证书总是缺这缺那。后来学乖了,每次生成证书前,都会看一眼配置文件里的 [ req ] 和 [ v3_req ] 段。
配置文件通常位于:
- Linux/macOS:
/usr/local/ssl/openssl.cnf或/etc/pki/tls/openssl.cnf - Windows: 安装目录下的
bin\cnf\openssl.cnf
里面最常用的几个段落:
| 段落名 | 作用 | 我常用的场景 |
|---|---|---|
[ req ] |
定义证书签名请求(CSR)的默认参数 | 设置默认的密钥长度、哈希算法 |
[ req_distinguished_name ] |
定义 CSR 中的 DN(Distinguished Name)字段 | 设置国家、组织、通用名称等默认值 |
[ v3_req ] |
定义 CSR 的 X.509 v3 扩展属性 | 添加 SAN(Subject Alternative Name) |
[ ca ] |
定义 CA 相关的默认策略 | 设置 CA 证书的有效期、路径长度约束 |
[ v3_req ] 里的 subjectAltName,导致生成的证书在 Chrome 浏览器里报“NET::ERR_CERT_COMMON_NAME_INVALID”。从 Chrome 58 开始,已经不再信任 Common Name 了,必须用 SAN。所以,如果你要生成用于 Web 服务器的证书,一定要在配置文件中加上 SAN 扩展。
2.3 常用命令概览
OpenSSL 的命令非常多,但日常工作中,常用的就那么十几个。我把它们分成了几类,方便你记忆。
密钥与证书生成类
genrsa/genpkey: 生成 RSA 私钥。我个人习惯用genpkey,因为它更通用,支持多种算法。req: 生成证书签名请求(CSR)或自签名证书。这是最常用的命令之一。x509: 显示证书内容、签名证书、转换证书格式。
信息查看类
version: 查看 OpenSSL 版本。ciphers: 列出支持的加密套件。s_client: 模拟 SSL/TLS 客户端连接,用于测试远程服务器的证书。
格式转换类
pkcs12: 处理 PKCS#12 格式(.p12 / .pfx)的证书和私钥。rsa/ec: 查看和转换 RSA/EC 私钥格式。
摘要与加密类
dgst: 计算文件的哈希值(如 SHA256)。enc: 对称加密/解密文件。rand: 生成随机数。这个我们下一节重点讲。
你看,其实核心命令就那么几个。我刚开始学的时候,把每个命令的 --help 都看了一遍,然后自己动手生成了一对测试证书。走完一遍流程,基本就记住了。
2.4 生成随机数
随机数在密码学里有多重要?这么说吧,没有好的随机数,你的私钥就可能被别人猜出来。OpenSSL 提供了专门的随机数生成器,它比编程语言自带的 random() 函数要安全得多。
基础用法
# 生成 32 字节(256 位)的随机数,以十六进制显示
openssl rand -hex 32
# 生成 16 字节的随机数,以 Base64 编码显示
openssl rand -base64 16
# 将随机数直接写入文件
openssl rand -out random.bin 64
-hex 和 -base64 是输出格式,32 和 16 是字节数。注意,这里指定的是字节数,不是位数。1 字节 = 8 位,所以 32 字节就是 256 位。
为什么不用系统自带的随机数?
你可能会问,Linux 下不是有 /dev/urandom 吗?为什么还要用 OpenSSL?
嗯,这里有个小故事。有一次我在一台嵌入式设备上做开发,那台设备的 /dev/urandom 因为硬件熵源不足,生成的随机数质量很差。结果导致我的密钥对出现了可预测的模式。后来我改用 OpenSSL 的 rand 命令,它内部会使用多种熵源混合,包括 CPU 的 RDRAND 指令(如果支持的话),安全性高得多。
说白了,OpenSSL 的随机数生成器是经过密码学认证的,它考虑了各种攻击场景。而系统自带的随机数,在某些极端环境下可能不够“随机”。
实际应用场景
生成随机数不只是为了好玩。在实际工作中,我经常用它来:
- 生成对称加密的密钥: 比如 AES-256 的密钥,正好需要 32 字节。
- 生成初始化向量(IV): 很多加密模式(如 CBC)需要一个随机的 IV。
- 生成会话 Token: 用于 API 认证的随机字符串。
- 生成盐值(Salt): 用于密码哈希,防止彩虹表攻击。
一个实用的例子: 生成一个 32 字节的随机密钥,并用它加密一个文件。
# 1. 生成 32 字节随机密钥,保存到文件
openssl rand -out mykey.bin 32
# 2. 用这个密钥加密文件(使用 AES-256-CBC 模式)
openssl enc -aes-256-cbc -salt -in secret.txt -out secret.enc -pass file:./mykey.bin
# 3. 解密
openssl enc -d -aes-256-cbc -in secret.enc -out secret_dec.txt -pass file:./mykey.bin
注意:-pass file:./mykey.bin 表示从文件中读取密码。这种方式比在命令行直接输入密码要安全,因为 ps 命令可能会泄露密码。
2.5 本章知识体系
为了让你更直观地理解这一章的内容,我画了一张图。它把 OpenSSL 的安装、配置、常用命令和随机数生成串在了一起。
这张图把这一章的核心内容都串起来了。你可以看到,安装和配置是地基,配置文件是大脑,常用命令是双手,而随机数生成则是安全性的保障。我建议你按照这个结构去学习,先装好工具,再理解配置,然后动手敲命令,最后用随机数生成来练手。这样走一遍,OpenSSL 的基本功就算打牢了。