OpenSSL 入门:从零开始认识这个加密工具箱

说实话,我刚接触 OpenSSL 那会儿,第一反应是「这玩意儿怎么这么难用?」命令行参数又多又怪,文档还全是英文。但用久了你会发现,它其实就是个瑞士军刀——功能全、体积小、哪儿都能用。

这一章,我带你把 OpenSSL 的底裤扒干净。从它是什么,到怎么装,再到日常最常用的几个命令,咱们一步到位。

OpenSSL 到底是什么?

OpenSSL 是一个开源的加密库,也是个命令行工具集。它实现了 SSL/TLS 协议,还提供了各种加密算法、证书操作、哈希计算等功能。

说白了,你在网上看到的 HTTPS 小锁图标,背后基本都是 OpenSSL 在干活。我当年第一次用 OpenSSL 生成自签名证书,配到 Nginx 上看到浏览器弹出「安全连接」的提示,那种成就感,啧,到现在还记得。

核心能力一览:

  • 对称加密:AES、DES、ChaCha20 等
  • 非对称加密:RSA、ECDSA、Ed25519
  • 哈希摘要:MD5、SHA-1、SHA-256、SHA-3
  • 数字证书:X.509 证书生成、签发、验证
  • SSL/TLS 协议:客户端/服务端通信
  • 随机数生成:密码学安全的伪随机数

安装与编译:别怕,其实就几步

不同系统装 OpenSSL 的方式不一样。我个人的建议是:能用包管理器就别自己编译。除非你有特殊需求,比如要定制算法模块或者交叉编译到嵌入式设备。

Linux(Ubuntu/Debian)

sudo apt update
sudo apt install openssl libssl-dev

macOS(Homebrew)

brew install openssl

macOS 自带的 OpenSSL 版本通常很老,我建议用 Homebrew 装一份新的。记得把路径加到 PATH 里:

export PATH="/usr/local/opt/openssl/bin:$PATH"

Windows

去官网下载安装包,或者用 Chocolatey:

choco install openssl

小技巧:装完后在终端敲 openssl version,如果看到版本号,说明装好了。我习惯先跑这条命令确认环境,省得后面踩坑。

从源码编译(进阶)

如果你非要自己编译,流程大概是这样的:

wget https://www.openssl.org/source/openssl-3.0.12.tar.gz
tar -xzf openssl-3.0.12.tar.gz
cd openssl-3.0.12
./Configure --prefix=/usr/local/openssl
make -j$(nproc)
sudo make install

嗯,这里要注意:编译 OpenSSL 3.x 需要 Perl 和 C 编译器。我曾经在 CentOS 7 上编译 3.0,结果系统自带的 Perl 版本太老,折腾了半天才搞定。所以,能用包管理器就别折腾自己。

常用命令概览:这些你早晚用得上

OpenSSL 的命令多到能写一本书,但日常工作中常用的就那么十几个。我把它们分成几类,你照着练就行。

1. 查看版本与帮助

openssl version
openssl help
openssl list -cipher-commands   # 列出所有加密命令

我个人习惯先跑 openssl version -a,能看到编译参数、默认路径、支持的算法列表。调试环境时特别有用。

2. 对称加密/解密

# 加密文件
openssl enc -aes-256-cbc -salt -in secret.txt -out secret.enc

# 解密文件
openssl enc -d -aes-256-cbc -in secret.enc -out secret.txt

它会提示你输入密码。注意:-salt 参数一定要加,否则加密强度会打折扣。我见过有人没加 salt,结果同样的密码加密同样的文件,每次输出都一样——这等于给攻击者留了后门。

3. 生成密钥对

# RSA 私钥(2048 位)
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048

# 从私钥提取公钥
openssl pkey -in private.pem -pubout -out public.pem

为什么用 2048 位?因为 1024 位已经被证明不够安全了,而 4096 位性能开销大。2048 位是目前业界公认的甜点值。

4. 生成自签名证书

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365

这条命令会生成一个有效期为 365 天的自签名证书。开发环境测试用这个就够了。生产环境?别闹,得用 CA 签发的证书。

5. 查看证书内容

openssl x509 -in cert.pem -text -noout

这条命令我几乎每天都要用。它能打印出证书的所有字段:颁发者、使用者、有效期、公钥、扩展项……排查证书问题时,它就是你的第一道防线。

6. 计算文件哈希

openssl dgst -sha256 myfile.txt
openssl dgst -md5 myfile.txt

MD5 现在基本只用来做文件完整性校验,别用在安全场景。SHA-256 是主流选择。

7. 测试 SSL/TLS 连接

openssl s_client -connect example.com:443

这条命令能模拟客户端发起 SSL/TLS 握手,把整个握手过程打印出来。我排查 HTTPS 连接问题时,第一个想到的就是它。比 curl 详细多了。

注意:s_client 默认不会验证证书链。要验证证书,需要加 -CAfile 或 -CApath 参数。我曾经在生产环境上直接用 s_client 测试,没加验证参数,结果证书过期了都没发现——血的教训。

知识体系总览

下面这张图,把 OpenSSL 的核心模块和它们之间的关系画出来了。你对照着看,心里就有谱了。

OpenSSL 核心知识体系 OpenSSL 核心知识体系 OpenSSL 加密算法库 SSL/TLS 协议 命令行工具 对称加密 非对称加密 哈希摘要 握手协议 记录协议 证书操作 加密/解密 连接测试 核心工作流 生成密钥对 → 创建证书签名请求(CSR) → 签发证书 → 配置服务端 → 客户端验证证书 → 建立 SSL/TLS 加密通道

常用命令速查表

我把最常用的命令整理成了表格,方便你快速查阅。建议收藏,用的时候直接翻。

用途 命令 说明
查看版本 openssl version -a 显示版本、编译参数、默认路径
对称加密 openssl enc -aes-256-cbc -salt -in f -out f.enc 加盐加密,安全性更高
生成 RSA 私钥 openssl genpkey -algorithm RSA -out key.pem 默认 2048 位
提取公钥 openssl pkey -in key.pem -pubout -out pub.pem 从私钥导出公钥
自签名证书 openssl req -x509 -newkey rsa:2048 -keyout k.pem -out c.pem -days 365 开发测试用
查看证书 openssl x509 -in cert.pem -text -noout 打印证书全部字段
计算 SHA-256 openssl dgst -sha256 file 文件完整性校验
测试 SSL 连接 openssl s_client -connect host:443 模拟 TLS 握手,调试用

我的习惯:每次装完 OpenSSL,我都会先跑一遍 openssl speed 测试本机加密性能。这样心里有个底,知道这台机器跑 RSA 2048 签名大概能到多少 TPS。生产环境压测时,这个数据能帮你快速定位瓶颈。

避坑指南

最后,分享几个我踩过的坑,你遇到了能少走弯路。

  • 版本兼容性:OpenSSL 1.x 和 3.x 的 API 有差异。如果你在写代码调用 libcrypto,记得检查版本。我曾在升级 OpenSSL 后忘了重新编译依赖它的程序,结果运行时疯狂报错。
  • 随机数种子:在嵌入式设备或容器里,系统熵源可能不足。OpenSSL 会卡在生成随机数那一步。解决办法是安装 haveged 或 rng-tools。
  • 证书路径:Linux 系统默认的 CA 证书路径是 /etc/ssl/certs。如果你自己编译 OpenSSL 并改了安装路径,记得设置 SSL_CERT_FILE 环境变量,否则验证证书时会失败。
  • 不要用 MD5 做安全校验:MD5 已经能被碰撞攻击了。我见过有人用 MD5 校验下载的软件包,结果被中间人替换了文件都没发现。用 SHA-256 吧,安全第一。