加密基础与算法:对称加密、非对称加密、哈希与密钥管理
各位好,咱们直接进入正题。加密这东西,说白了就是给数据加把锁。你想想看,存储系统里存着用户密码、交易记录、企业机密——要是明文裸奔,那跟把保险柜门敞开有什么区别?
我刚开始做存储那会儿,觉得加密就是调个库、传个参数的事。直到有一次做安全审计,发现密钥硬编码在配置文件里……嗯,从那以后我再也不敢小看加密了。今天咱们把四种核心武器讲透:AES、RSA、SHA-256、密钥管理。
核心原则:加密不是为了防住所有攻击者,而是让攻击成本远高于数据价值。你不需要造轮子,但必须知道轮子怎么转。
对称加密:AES 算法
对称加密,就是加密和解密用同一把钥匙。你想想看,就像你家大门——钥匙既能锁门也能开门。AES 是目前最主流的对称加密标准,没有之一。
我个人习惯用 AES-256-GCM 模式。为什么?因为 GCM 模式自带认证标签,能同时保证机密性和完整性。我在项目中遇到过有人用 AES-ECB 模式加密数据库字段——结果相同明文产生相同密文,攻击者一看就知道哪些记录重复。这简直是给黑客送情报。
| AES 模式 | 特点 | 推荐场景 |
|---|---|---|
| ECB | 简单,但相同明文→相同密文 | 不要用 |
| CBC | 需要 IV,可并行解密 | 文件加密(旧系统兼容) |
| GCM | 认证加密,抗篡改 | 首选:网络传输、存储加密 |
| CTR | 可并行,无填充 | 高性能场景 |
我的建议:新项目一律用 AES-256-GCM。密钥长度选 256 位,IV 用 12 字节随机数。别自己拼凑加密方案——GCM 已经帮你处理了认证问题。
// Go 语言示例:AES-256-GCM 加密
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
)
func encrypt(plaintext []byte, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
nonce := make([]byte, gcm.NonceSize())
if _, err := rand.Read(nonce); err != nil {
return nil, err
}
// 密文 = nonce + 加密数据 + 认证标签
return gcm.Seal(nonce, nonce, plaintext, nil), nil
}
非对称加密:RSA 算法
非对称加密,有两把钥匙:公钥加密,私钥解密。公钥可以公开,私钥必须保密。这解决了对称加密最大的痛点——密钥分发问题。
但 RSA 有个硬伤:慢。你想想看,RSA-2048 加密 1KB 数据,比 AES-256 慢几千倍。所以实际项目中,没人用 RSA 直接加密大文件。怎么做?混合加密:用 RSA 加密 AES 密钥,再用 AES 加密数据。
我曾经帮一个团队排查性能问题,他们直接用 RSA 加密每一条日志记录……结果加密耗时比业务逻辑还长。改成混合加密后,性能提升了 40 倍。
避坑指南:RSA 的填充模式很重要。PKCS#1 v1.5 有历史漏洞,建议用 OAEP 填充。密钥长度至少 2048 位,4096 位更安全但性能下降明显。
// RSA-OAEP 加密示例
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
)
func rsaEncrypt(plaintext []byte, pubKey *rsa.PublicKey) ([]byte, error) {
return rsa.EncryptOAEP(sha256.New(), rand.Reader, pubKey, plaintext, nil)
}
哈希算法:SHA-256
哈希算法不是加密,是摘要。输入任意长度数据,输出固定长度哈希值。而且不可逆——你没法从哈希值反推出原文。
SHA-256 是 SHA-2 家族的一员,输出 256 位(32 字节)哈希值。它在存储系统里主要有两个用途:
- 数据完整性校验:文件上传后计算哈希,下载时重新计算,对比是否一致
- 密码存储:存密码的哈希值,而不是明文
但注意:不要直接用 SHA-256 存密码。为什么?因为彩虹表攻击。攻击者预计算常见密码的哈希值,一查就知道你的密码。正确的做法是加盐(salt)并多次迭代,比如用 bcrypt、scrypt 或 Argon2。
关键区别:SHA-256 是快速哈希,适合校验完整性;密码哈希需要慢速哈希(如 bcrypt),让暴力破解成本高到不可接受。
// SHA-256 计算文件哈希
import (
"crypto/sha256"
"io"
"os"
)
func fileHash(path string) ([]byte, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
h := sha256.New()
if _, err := io.Copy(h, f); err != nil {
return nil, err
}
return h.Sum(nil), nil
}
密钥管理基础
算法选得再好,密钥泄露一切白搭。密钥管理是加密体系中最薄弱的环节——我见过太多团队在算法上花大功夫,却把密钥写在配置文件里。
密钥管理有几个核心原则:
- 密钥分级:主密钥加密工作密钥,工作密钥加密数据。这样即使工作密钥泄露,也只影响部分数据
- 密钥轮换:定期更换密钥,降低单次泄露的影响范围
- 硬件保护:高安全场景用 HSM(硬件安全模块)或 TPM(可信平台模块)存储密钥
- 访问控制:密钥只能被授权服务访问,通过 KMS(密钥管理服务)统一管理
| 存储方式 | 安全等级 | 适用场景 |
|---|---|---|
| 环境变量 | 低 | 开发测试环境 |
| 配置文件(加密) | 中 | 小型部署 |
| KMS(如 AWS KMS / HashiCorp Vault) | 高 | 生产环境 |
| HSM | 极高 | 金融、政务等高合规场景 |
我的经验:别自己写密钥管理逻辑。用现成的 KMS 或 Vault,它们已经处理了密钥轮换、审计日志、访问控制这些麻烦事。你只需要关注业务逻辑。
嗯,到这里加密基础就讲完了。记住一句话:算法是工具,密钥管理是防线。选对工具,守好防线,你的存储系统才能经得起实战考验。