2026-04-09 01:28:15 +08:00

503 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OpenSSL
> OpenSSL 是开源的 SSL/TLS 工具包,用于实现加密通信和数据安全。
---
## 1. 加密算法概述
### 1.1 对称加密
**特性**
- 加密和解密使用同一个密钥,效率高
- 将原始数据分割成固定大小的块,逐个进行加密
**缺陷**
- 密钥过多:需要管理大量密钥
- 密钥分发:安全分发密钥困难
- 数据来源无法确认
**常见算法**
| 算法 | 密钥长度 | 说明 |
|------|---------|------|
| DES | 56 bits | 废弃,安全性低 |
| 3DES | 168 bits | 废弃,兼容性差 |
| **AES** | 128/192/256 bits | 当前主流 |
| Blowfish | 可变 | 开源免费 |
| Twofish | 128/192/256 bits | AES 候选 |
**使用示例**
```bash
# 加密
openssl enc -aes-256-cbc -in plain.txt -out cipher.bin -pass pass:mypassword
# 解密
openssl enc -d -aes-256-cbc -in cipher.bin -pass pass:mypassword
```
### 1.2 非对称加密(公钥加密)
#### 1.2.1 基础概念
**密钥对**
- **公钥**public key公开给所有人用于加密
- **私钥**secret key自己留存用于解密/签名
**功能**
- 数据加密:适合加密较小数据(如对称密钥)
- 数字签名:确认发送方身份
**缺点**:密钥长、算法复杂、效率低
#### 1.2.2 加密原理
```
接收者 B
1. 生成密钥对 (公钥 Pb, 私钥 Sb)
2. 公开公钥 Pb保管好私钥 Sb
发送者 A
1. 使用接收者公钥 Pb 加密数据 M
2. 发送加密数据 Pb(M) 给 B
接收者 B
1. 使用私钥 Sb 解密
2. 得到原始数据 M = Sb(Pb(M))
```
#### 1.2.3 数字签名原理
```
发送者 A
1. 生成密钥对 (公钥 Pa, 私钥 Sa)
2. 公开公钥 Pa保管好私钥 Sa
3. 使用私钥 Sa 对数据 M 签名
4. 发送 (M, Sa(M)) 给接收者 B
接收者 B
1. 使用发送者公钥 Pa 验证签名
2. 验证通过 = 确认数据来自 A 且未被篡改
```
> **关键**:私钥签名,公钥验证。签名只能由私钥产生,任何人可用公钥验证。
#### 1.2.4 常见算法对比
| 算法 | 密钥长度 | 用途 | 安全性 | 性能 |
|------|---------|------|--------|------|
| **RSA** | 2048/4096 bits | 加密/签名 | 高 | 慢 |
| **DSA** | 1024/2048 bits | 仅签名 | 高 | 快 |
| **ECC** | 256/384 bits | 加密/签名 | 高 | 快 |
| **Ed25519** | 256 bits | 仅签名 | 最高 | 最快 |
#### 1.2.5 RSA 算法详解
**数学原理**
- 基于大整数分解难题
- 两个大素数相乘容易,但分解乘积困难
- RSA 取名来自 Rivest、Shamir、Adleman 三位发明者
**密钥生成过程**
```
1. 选择两个大素数 p 和 q
2. 计算 n = p × q
3. 计算 φ(n) = (p-1)(q-1)
4. 选择 e满足 1 < e < φ(n) 且 gcd(e, φ(n)) = 1
5. 计算 d满足 d × e ≡ 1 (mod φ(n))
6. 公钥 = (n, e)
7. 私钥 = (n, d)
```
**数学公式**
```
加密M^e mod n = C
解密C^d mod n = M
签名H(M)^d mod n = S
验证S^e mod n = H(M)
```
**密钥长度选择**
| 密钥长度 | 安全性 | 推荐场景 |
|----------|--------|----------|
| 1024 bits | 不安全 | 已废弃 |
| 2048 bits | 安全 | 个人/小型业务 |
| 4096 bits | 高安全 | 金融/政府 |
#### 1.2.6 ECC椭圆曲线密码学
**优势**
- 相同安全强度下,密钥更短
- 256-bit ECC ≈ 2048-bit RSA
- 计算更快,资源消耗更低
**曲线类型**
| 曲线 | 密钥长度 | 应用 |
|------|---------|------|
| secp256r1 (P-256) | 256 bits | 通用 |
| secp384r1 (P-384) | 384 bits | 高安全 |
| secp521r1 (P-521) | 521 bits | 最高安全 |
**OpenSSL 生成 ECC 密钥**
```bash
# 生成 ECC 私钥secp256r1
openssl genpkey -algorithm EC -out ec Private key.pem -pkeyopt ec_paramgen_curve:secp256r1
# 生成 ECC CSR
openssl req -new -key ec_private.key -out request.csr
# 自签名 ECC 证书
openssl req -new -x509 -key ec_private.key -out cert.pem
```
#### 1.2.7 Ed25519现代签名算法
**特点**
- 现代签名算法,高性能
- 密钥短256 bits签名短64 bytes
- 安全性极高,无侧信道攻击风险
**生成密钥**
```bash
# Ed25519 私钥
openssl genpkey -algorithm ed25519 -out ed25519key.pem
# 自签名证书
openssl req -new -x509 -key ed25519key.pem -out cert.pem
```
#### 1.2.8 非对称加密实战
**RSA 加密文件**
```bash
# 方法1使用公钥加密
openssl rsautl -encrypt -pubin -inkey pub.key -in plaintext.txt -out ciphertext.bin
# 方法2使用私钥签名
openssl rsautl -sign -inkey priv.key -in data.txt -out signature.bin
```
**AES 密钥交换(混合加密)**
```bash
# 1. 生成随机 AES 密钥
openssl rand -hex 32 > aes.key
# 2. 用接收者公钥加密 AES 密钥
openssl rsautl -encrypt -pubin -inkey recipient_pub.key -in aes.key -out aes.key.enc
# 3. 用 AES 加密数据
openssl enc -aes-256-cbc -in data.txt -out data.enc -pass file:aes.key
# 接收者解密
# 1. 用私钥解密 AES 密钥
openssl rsautl -decrypt -inkey recipient_priv.key -in aes.key.enc -out aes.key
# 2. 用 AES 解密数据
openssl enc -d -aes-256-cbc -in data.enc -pass file:aes.key
```
#### 1.2.9 算法选择建议
| 场景 | 推荐算法 | 原因 |
|------|---------|------|
| HTTPS/TLS | ECDHE + RSA/ECDSA | 性能与安全平衡 |
| 代码签名 | Ed25519 或 RSA-2048 | 高安全性 |
| 文档签名 | Ed25519 | 快速、签名短 |
| 密钥交换 | ECDH 或 RSA | 成熟稳定 |
| IoT 设备 | ECC | 资源受限 |
---
## 2. 非对称加密算法详解
### 2.1 RSA
**生成 RSA 密钥**
```bash
# 标准 RSA 私钥2048位
openssl genrsa -out rsa_private.key 2048
# 带密码保护的 RSA 私钥
openssl genrsa -aes256 -out rsa_private.key 2048
# 提取公钥
openssl rsa -in rsa_private.key -pubout -out rsa_public.key
# 查看密钥信息
openssl rsa -in rsa_private.key -noout -text
```
**加解密**
```bash
# 加密(使用公钥)
openssl rsautl -encrypt -pubin -inkey pub.key -in plaintext.txt -out encrypted.bin
# 解密(使用私钥)
openssl rsautl -decrypt -inkey priv.key -in encrypted.bin -out decrypted.txt
# 签名(使用私钥)
openssl rsautl -sign -inkey priv.key -in data.txt -out signature.bin
# 验证(使用公钥)
openssl rsautl -verify -pubin -inkey pub.key -in signature.bin -signed data.txt
```
### 2.2 DSA
> DSA 仅用于签名,不能加密解密。
```bash
# 生成 DSA 参数
openssl dsaparam -out dsaparam.pem 2048
# 生成 DSA 私钥
openssl gendsaparam dsaparam.pem -out dsa_private.key
# 生成 CSR
openssl req -new -key dsa_private.key -out request.csr
# 签名
openssl dgst -sha256 -sign dsa_private.key -out signature.bin data.txt
```
### 2.3 DH密钥交换
```bash
# 生成 DH 参数
openssl dhparam -out dhparam.pem 2048
# 生成 DH 私钥
openssl genpkey -paramfile dhparam.pem -out dh_private.key
# 提取公钥
openssl pkey -in dh_private.key -pubout -out dh_public.key
```
---
## 3. 单向哈希算法
### 3.1 基础概念
将任意数据转换为固定长度的"指纹"(摘要)。
**特性**
- 任意长度输入,固定长度输出
- 雪崩效应:数据微小改变,指纹变化巨大
- 单向性:无法从指纹恢复原数据
### 3.2 常见算法
| 算法 | 输出长度 | 安全性 |
|------|---------|--------|
| md5 | 128 bits | 不安全,仅用于兼容性 |
| sha1 | 160 bits | 弱安全,不推荐 |
| sha256 | 256 bits | 推荐 |
| sha512 | 512 bits | 推荐 |
| blake2b | 可变 | 高性能,高安全 |
### 3.3 常用命令
```bash
echo -n "hello" | md5sum
sha256sum file
openssl dgst -sha256 file
带密钥的哈希HMAC
openssl dgst -sha256 -hmac "mykey" file
```
---
## 4. 密钥交换
### 4.1 DHDiffie-Hellman
让双方通过不安全信道建立共享密钥。
**原理**
```
A: 选取 g, p → 计算 g^a%p → 发送给 B
B: 选取 g, p → 计算 g^b%p → 发送给 A
A: 计算 (g^b%p)^a%p = g^ab%p → 密钥
B: 计算 (g^a%p)^b%p = g^ab%p → 密钥
```
> 私密数据 a、b 在生成密钥后丢弃,不长期存储,安全性高。
### 4.2 ECDH椭圆曲线 DH
更短密钥,更高安全性。
---
## 5. TLS/SSL 协议
### 5.1 协议版本
| 版本 | 年份 | 状态 |
|------|------|------|
| SSL 1.0 | 1994 | 从未公开 |
| SSL 2.0 | 1995 | 废弃,有漏洞 |
| SSL 3.0 | 1996 | 废弃POODLE |
| TLS 1.0 | 1999 | 废弃BEAST |
| TLS 1.1 | 2006 | 废弃 |
| **TLS 1.2** | 2008 | 推荐 |
| **TLS 1.3** | 2018 | 当前最佳 |
### 5.2 TLS 1.3 改进
- 更快的握手1-RTT / 0-RTT
- 移除不安全算法MD5、SHA1、RC4
- 前向保密FS强制
- 简化密码套件
### 5.3 密码套件格式
```
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
│ │ │ │ │
│ │ │ │ 摘要算法
│ │ │ 对称加密算法
│ │ 密钥协商算法
│ 签名算法
密钥交换算法
```
---
## 6. CA 与证书
### 6.1 PKI 架构
```
CA证书颁发机构
├── Root CA根CA- 自签,可信锚点
├── Intermediate CA中间CA- 签名子CA
└── 最终用户/服务器
```
### 6.2 证书格式
| 格式 | 说明 |
|------|------|
| PEM | Base64 文本 |
| DER | 二进制 |
| PKCS#12 | 含私钥(.pfx/.p12 |
| PKCS#7 | 证书链(.p7b/.p7c |
### 6.3 自建 CA 与证书管理
```bash
# 创建目录
mkdir -p /etc/pki/CA/{certs,crl,newcerts,private}
touch /etc/pki/CA/index.txt
echo 01 > /etc/pki/CA/serial
# CA 私钥
openssl genrsa -aes256 -out /etc/pki/CA/private/cakey.pem 2048
# 自签 CA
openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem -days 3650
# 用户申请证书
openssl genrsa -out user.key 2048
openssl req -new -key user.key -out user.csr
openssl ca -in user.csr -out user.crt -days 365
```
### 6.4 证书吊销
```bash
# 吊销证书
openssl ca -revoke /etc/pki/CA/newcerts/11.pem
# 查看状态
openssl ca -status 11
# 生成 CRL
openssl ca -gencrl -out /etc/pki/CA/crl/crl.pem
```
---
## 7. 实战应用
### 7.1 生成强密钥
```bash
# RSA 4096位
openssl genrsa -aes256 4096 > server.key
# ECC
openssl genpkey -algorithm EC -out ec.key -pkeyopt ec_paramgen_curve:secp256r1
# Ed25519
openssl genpkey -algorithm ed25519 -out ed25519.key
```
### 7.2 测试 TLS 连接
```bash
openssl s_client -connect example.com:443 -showcerts
openssl s_client -tls1_2 -connect example.com:443
```
### 7.3 随机数与哈希
```bash
openssl rand -hex 32
openssl dgst -sha256 file
```
---
## 8. 常用命令速查
### 8.1 密钥操作
| 场景 | 命令 |
|------|------|
| 生成 RSA 私钥 | `openssl genrsa -out key.pem 2048` |
| 生成 RSA 私钥(带密码) | `openssl genrsa -aes256 -out key.pem 2048` |
| 提取公钥 | `openssl rsa -in key.pem -pubout -out pub.key` |
| 查看密钥 | `openssl rsa -in key.pem -noout -text` |
### 8.2 证书操作
| 场景 | 命令 |
|------|------|
| 生成 CSR | `openssl req -new -key key.pem -out req.csr` |
| 自签证书 | `openssl req -new -x509 -key key.pem -out cert.pem` |
| CA 签发 | `openssl ca -in req.csr -out cert.pem` |
| 验证证书 | `openssl verify -CAfile ca.pem cert.pem` |
| 查看证书 | `openssl x509 -in cert.pem -noout -text` |
### 8.3 加密/签名
| 场景 | 命令 |
|------|------|
| RSA 加密 | `openssl rsautl -encrypt -pubin -inkey pub.key -in f.txt -out f.enc` |
| RSA 解密 | `openssl rsautl -decrypt -inkey priv.key -in f.enc -out f.txt` |
| 签名 | `openssl dgst -sha256 -sign priv.key -out sig.bin data.txt` |
| 验证 | `openssl dgst -sha256 -verify pub.key -signature sig.bin data.txt` |
---
## 9. 小结
| 类别 | 用途 | 推荐算法 |
|------|------|----------|
| 对称加密 | 数据加密 | AES-256 |
| 非对称加密 | 密钥交换 | RSA-2048 / ECDH |
| 数字签名 | 身份认证 | Ed25519 / RSA-2048 / ECDSA |
| 单向哈希 | 完整性校验 | SHA-256 |
| 密钥交换 | 协商会话密钥 | ECDH / X25519 |
掌握非对称加密的核心概念:
- **公钥加密,私钥解密**:保密通信
- **私钥签名,公钥验证**:身份认证
- **混合加密**:用对称加密数据,用非对称加密密钥,兼顾效率与安全
> 生产环境推荐TLS 1.3 + ECDHE-ECDSA + AES-256-GCM + SHA-384