OpenSSL 核心概念

FreeGuideOnline 最新 2026-07-14

bash openssl enc -aes-256-cbc -salt -in plain.txt -out encrypted.bin

解密此文件:
```bash
openssl enc -d -aes-256-cbc -in encrypted.bin -out decrypted.txt

这里的 -salt 会增加随机性,防止相同明文和相同密码总是产生相同的密文。

对称加密是实现安全通信的基础组件,但它无法解决密钥交换问题,于是我们需要非对称加密。


非对称加密

非对称加密完美地解决了对称密钥的安全传递问题。它使用一对数学上相关但无法相互推导的密钥:一个可以公开给所有人的“公钥”,另一个必须严格保密的“私钥”。

它的工作原理是:

  • 用公钥加密的数据,只能用对应的私钥解密
  • 用私钥加密的数据,则可以用公钥解密(这种特性更多用于数字签名)。

你可以把公钥想象成一个随处可得的开着的锁,任何人拿到锁都可以把它扣上(加密数据),但只有拥有唯一对应钥匙(私钥)的人才能打开这把锁(解密数据)。

在 OpenSSL 中的体现

生成一对 RSA 私钥和公钥:

# 生成一个 2048 位的 RSA 私钥
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

# 从私钥中提取出对应的公钥
openssl rsa -pubout -in private_key.pem -out public_key.pem

用公钥加密一个文件,只有持有私钥的人才能解密:

# 加密
openssl pkeyutl -encrypt -pubin -inkey public_key.pem -in plain.txt -out enc.bin
# 解密
openssl pkeyutl -decrypt -inkey private_key.pem -in enc.bin -out dec.txt

由于非对称加密计算量巨大,性能远低于对称加密,在实践中它通常只用来安全地传输一个“会话密钥”,这个会话密钥才是后续对称加密所用的密钥。这就是 SSL/TLS 协议的核心思路。


哈希算法

哈希函数(又称散列函数)是一种单向的数学函数,它将任意长度的数据转换成一段固定长度的“摘要”。这个过程不可逆,你无法从摘要倒推出原始数据。

关键特性

  • 确定性:相同的输入永远产生相同的哈希值。
  • 固定输出:无论输入是 1 个字还是整部电影,输出的哈希值长度固定(如 SHA-256 始终输出 256 位)。
  • 抗碰撞性:极难找到两个不同的输入产生相同的哈希值。
  • 雪崩效应:哪怕只修改输入中的一位,输出的哈希值也会面目全非。

常见算法

MD5(已破解,不推荐),SHA-1(已过时),SHA-256 / SHA-384 / SHA-512(目前主流)。

在 OpenSSL 中的体现

计算文本文件的 SHA-256 哈希:

openssl dgst -sha256 file.txt

哈希主要用于验证数据完整性。下载文件时常看到一个散列值,你可以重新计算一遍并比对,确保文件没有被篡改。同时,哈希也是构建数字签名和证书必不可少的一环。


数字签名

数字签名是将非对称加密与哈希算法相结合的产物。它解决了两个核心问题:身份认证数据完整性

签名过程(由发送者执行):

  1. 对要发送的数据计算哈希值。
  2. 使用发送者的私钥对这个哈希值进行加密,生成签名。
  3. 将原始数据与签名一起发送。

验证过程(由接收者执行):

  1. 收到数据后,用同样的哈希算法重新计算数据的哈希值。
  2. 同时使用发送者的公钥解密签名,得到签名里的哈希值。
  3. 比对两个哈希值。如果相同,则证明:数据在传输过程中未被篡改(完整性),且该签名必定来自持有对应私钥的那个人(身份认证)。

在 OpenSSL 中的体现

用私钥对一个文件签名:

openssl dgst -sha256 -sign private_key.pem -out signature.bin data.txt

用公钥验证签名:

openssl dgst -sha256 -verify public_key.pem -signature signature.bin data.txt

看到 Verified OK 就代表验证成功。


数字证书与公钥基础设施(PKI)

非对称加密和数字签名完美运行时,还有一个根本问题需要解决:你如何确信公钥确实属于你想通信的那个实体?

一个攻击者完全可以生成自己的一对密钥,然后冒充“bank.com”把假公钥发给你。你如果用这个假公钥加密敏感信息,攻击者就能用自己的私钥解密。

为了解决这个问题,引入了数字证书和整个公钥基础设施(PKI)。

数字证书

数字证书就像是“互联网世界的身份证”。它由受信任的第三方——**证书颁发机构(CA)**签发。一个标准的 X.509 证书包含了:

  • 持有者的信息(域名、组织等)
  • 持有者的公钥
  • 证书的有效期
  • 颁发机构的信息
  • CA 的数字签名

CA 在签发证书前,会验证申请者确实是域名的拥有者。当你的浏览器访问一个 HTTPS 网站时,它收到网站的证书,会使用内置的 CA 根证书中的公钥来验证证书上的 CA 签名。如果验证通过,浏览器就可以信任证书中的公钥确实是该网站的,进而安全地交换对称密钥。

证书链

CA 本身又是由更高级的 CA 签发的,最终形成一条证书链,链的顶端是根证书。根证书必须被操作系统或浏览器预先信任并内置。浏览器验证服务端证书时,会逐级向上验证签名,直到找到自己信任的根证书。

常见证书类型:

  • 根证书:自签名,绝对信任。
  • 中间证书:由根证书或其他中间证书签发,用于签发最终的用户证书,保护根证书私钥不常在线。
  • 终端实体证书(叶子证书):颁发给网站、服务器,实际用于 TLS 握手。

在 OpenSSL 中的体现

OpenSSL 可以模拟一个完整的迷你 CA,帮助你深刻理解证书体系。

  1. 创建一个自签名根证书。
  2. 使用根证书签发一个中间证书。
  3. 使用中间证书签发一个服务器证书。
  4. 在服务器上配置服务器证书和中间证书,客户端配置根证书信任,就能完成双向验证。

相关命令示例:

# 生成自签名根证书
openssl req -new -x509 -key root.key -out root.crt -days 3650

# 创建服务器证书签署请求(CSR)
openssl req -new -key server.key -out server.csr

# 用根证书签发服务器证书(实际环境中会用中间证书签发)
openssl x509 -req -in server.csr -CA root.crt -CAkey root.key -CAcreateserial -out server.crt -days 365