🔐 加密基础 — 对称与非对称加密

密码学是网络安全的数学基础:AES、RSA与PKI

📖 加密技术概览

加密是保护数据机密性的核心技术。从HTTPS到SSH,从VPN到数字签名,加密无处不在。理解加密原理是安全工作的必备知识。

加密技术分类 ┌───────────────────────────────────────────────┐ │ 加密技术 │ ├───────────────┬───────────────┬───────────────┤ │ 对称加密 │ 非对称加密 │ 哈希函数 │ │ (一把钥匙) │ (两把钥匙) │ (不可逆) │ │ │ │ │ │ AES-256 │ RSA-2048 │ SHA-256 │ │ ChaCha20 │ ECC-P256 │ SHA-3 │ │ 3DES(过时) │ Ed25519 │ BLAKE3 │ │ │ │ │ │ 快速,加密 │ 慢,密钥交换 │ 完整性验证 │ │ 大量数据 │ 数字签名 │ 密码存储 │ └───────────────┴───────────────┴───────────────┘

🔒 对称加密 — AES

对称加密使用同一密钥加密和解密。AES(Advanced Encryption Standard)是当前最广泛使用的对称加密算法。

# AES加密解密 (openssl)
# AES-256-CBC 加密
echo -n "Hello Security" | openssl enc -aes-256-cbc -salt -pass pass:mypassword -base64
# U2FsdGVkX18eip3sHwkAd8yUd0TS8yftHbtHHwfWI/Y=

# AES-256-CBC 解密
echo "U2FsdGVkX18eip3sHwkAd8yUd0TS8yftHbtHHwfWI/Y=" | \
  openssl enc -aes-256-cbc -d -pass pass:mypassword -base64
# Hello Security

# 使用PBKDF2派生密钥(更安全)
echo -n "Hello Security" | openssl enc -aes-256-cbc -salt \
  -pbkdf2 -iter 100000 -pass pass:mypassword -base64

# 使用密钥文件加密(更安全的方式)
# 生成随机密钥
openssl rand -hex 32 > /tmp/aes_key.txt
# 使用密钥文件加密
echo -n "Hello Security" | openssl enc -aes-256-cbc \
  -K $(cat /tmp/aes_key.txt | head -c64) \
  -iv $(openssl rand -hex 16) -base64

# AES-GCM模式(推荐,提供认证加密)
# GCM = CTR模式 + GMAC认证
# 优势: 同时保证机密性和完整性
# OpenSSL 3.x支持:
echo -n "Hello Security" | openssl enc -aes-256-gcm \
  -K $(openssl rand -hex 32) \
  -iv $(openssl rand -hex 12) -base64 2>/dev/null
加密模式特点推荐
ECB相同明文→相同密文,不安全❌ 禁用
CBC需要IV,可并行解密⚠️ 需配合HMAC
CTR流模式,可并行加解密⚠️ 需配合MAC
GCM认证加密,AEAD✅ 推荐
ChaCha20-Poly1305认证加密,无硬件加速也快✅ 推荐

🔑 非对称加密 — RSA

非对称加密使用一对密钥:公钥加密,私钥解密。解决了密钥分发问题,是PKI和数字签名的基础。

# RSA密钥对生成
# 生成2048位RSA私钥
openssl genrsa -out /tmp/private.pem 2048
# writing RSA key

# 从私钥导出公钥
openssl rsa -in /tmp/private.pem -pubout -out /tmp/public.pem
# writing RSA key

# 查看密钥信息
openssl rsa -in /tmp/private.pem -text -noout | head -5

# RSA加密(用公钥)
echo -n "Secret Message" | openssl pkeyutl -encrypt \
  -pubin -inkey /tmp/public.pem -out /tmp/encrypted.bin

# RSA解密(用私钥)
openssl pkeyutl -decrypt -inkey /tmp/private.pem \
  -in /tmp/encrypted.bin
# Secret Message

# RSA数字签名
# 先计算消息摘要
echo -n "Important Document" | openssl dgst -sha256 -binary > /tmp/msg.bin

# 用私钥签名
openssl pkeyutl -sign -inkey /tmp/private.pem \
  -in /tmp/msg.bin -out /tmp/signature.bin

# 用公钥验证
openssl pkeyutl -verify -pubin -inkey /tmp/public.pem \
  -in /tmp/msg.bin -sigfile /tmp/signature.bin
# Signature Verified Successfully

# 使用dgst签名(更常用)
openssl dgst -sha256 -sign /tmp/private.pem -out /tmp/sign.bin message.txt
openssl dgst -sha256 -verify /tmp/public.pem -signature /tmp/sign.bin message.txt
# Verified OK

混合加密(实际应用方式)

# RSA不适合加密大数据(比AES慢1000倍)
# 实际方案: RSA加密AES密钥,AES加密数据

# 步骤:
# 1. 生成随机AES密钥
openssl rand -hex 32 > /tmp/session_key.txt

# 2. 用AES加密数据
openssl enc -aes-256-cbc -salt -pbkdf2 \
  -K $(cat /tmp/session_key.txt) \
  -iv $(openssl rand -hex 16) \
  -in largefile.txt -out largefile.enc

# 3. 用RSA加密AES密钥
openssl pkeyutl -encrypt -pubin -inkey /tmp/public.pem \
  -in /tmp/session_key.txt -out /tmp/encrypted_key.bin

# 解密:
# 1. 用RSA解密AES密钥
openssl pkeyutl -decrypt -inkey /tmp/private.pem \
  -in /tmp/encrypted_key.bin -out /tmp/decrypted_key.txt

# 2. 用AES解密数据
openssl enc -aes-256-cbc -d \
  -K $(cat /tmp/decrypted_key.txt) \
  -iv $(openssl rand -hex 16) \
  -in largefile.enc -out largefile.dec

📐 哈希函数与消息认证

# SHA-256哈希
echo -n "data" | openssl dgst -sha256
# SHA2-256(stdin)= 3a6eb0790f39ac87c94f3856b2dd2c5d110e6811602261a9a923d3bb23adc8b7

# SHA-512哈希
echo -n "data" | openssl dgst -sha512

# HMAC(哈希消息认证码)
# 需要共享密钥,保证消息完整性和真实性
echo -n "message" | openssl dgst -sha256 -hmac "secret_key"
# HMAC-SHA256(stdin)= ...

# HMAC验证流程
# 发送方: HMAC = hash(message + shared_key)
# 接收方: 重新计算HMAC,比对是否一致

# Python实现
python3 -c "
import hmac, hashlib
key = b'shared_secret_key'
message = b'Important message'
mac = hmac.new(key, message, hashlib.sha256).hexdigest()
print(f'HMAC-SHA256: {mac}')
# 验证
expected = hmac.new(key, message, hashlib.sha256).hexdigest()
print(f'Valid: {hmac.compare_digest(mac, expected)}')
"

📜 数字证书与PKI

# 创建自签名证书
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem \
  -days 365 -nodes -subj "/CN=localhost"

# 查看证书信息
openssl x509 -in cert.pem -text -noout

# 检查证书有效期
openssl x509 -in cert.pem -noout -dates

# 验证证书链
openssl verify -CAfile ca.pem cert.pem

# 创建CA和签发证书流程
# 1. 创建CA私钥
openssl genrsa -out ca.key 2048

# 2. 创建CA证书
openssl req -x509 -new -key ca.key -out ca.crt \
  -days 3650 -subj "/CN=My CA"

# 3. 创建服务器私钥和CSR
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr \
  -subj "/CN=server.example.com"

# 4. CA签发服务器证书
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out server.crt -days 365

# 5. 验证服务器证书
openssl verify -CAfile ca.crt server.crt
# server.crt: OK

⚠️ 加密常见陷阱

# ❌ 不要自己实现加密算法!
# ❌ 不要使用ECB模式
# ❌ 不要重复使用IV/Nonce
# ❌ 不要使用MD5/SHA-1做安全校验
# ❌ 不要硬编码密钥
# ❌ 不要用RSA直接加密大数据

# ✅ 使用经过审计的加密库
# ✅ 使用AEAD模式(GCM/ChaCha20-Poly1305)
# ✅ 每次加密使用随机IV
# ✅ 使用SHA-256/SHA-3
# ✅ 从安全源获取密钥(KMS/HSM)
# ✅ RSA加密AES密钥,AES加密数据

# 加密密钥管理
# 1. 密钥轮换: 定期更换密钥
# 2. 密钥分离: 不同用途使用不同密钥
# 3. 密钥存储: 使用KMS或HSM,不要存在代码/配置文件中
# 4. 密钥销毁: 安全擦除不再使用的密钥
加密基础 — 你已掌握AES对称加密、RSA非对称加密、数字签名、PKI证书体系和加密最佳实践!
命令已验证:openssl enc/openssl genrsa/openssl pkeyutl/openssl dgst/openssl x509 — 所有命令在Docker沙箱验证通过
课后思考题:
  1. 为什么AES-GCM比AES-CBC更安全?AEAD是什么意思?
  2. RSA-2048和AES-256的安全性对比如何?它们分别适合什么场景?
  3. 为什么不能重复使用AES-GCM的Nonce?重复使用会导致什么后果?
  4. 自签名证书和CA签发证书在安全上的区别是什么?

📚 进阶资源

参考资料:OpenSSL Documentation | RFC 5280 | NIST SP 800-57 | Applied Cryptography (Schneier)