加密基础概念:对称加密、非对称加密、哈希、数字签名与 KMS
好,我们直接进入正题。第二节课要啃的,是加密领域最核心的几个概念。你想想看,不管你做的是对象存储上传下载,还是别的什么安全系统,绕不开的都是对称加密、非对称加密、哈希函数、数字签名,还有那个听起来很玄乎的密钥管理服务(KMS)。
我个人做 SDK 这么多年,见过太多开发者在“加密”这两个字上栽跟头。有的是选错了加密算法,有的是密钥硬编码在代码里直接拉去生产——嗯,今天就带你把每个概念彻底理清楚,不是背定义,而是知道它干什么用、怎么用、有什么坑。
本章思维导图
对称加密 — 又快又简单,但密钥怎么传?
对称加密,说白了就是 加密和解密用同一个密钥。你拿它加密一段数据,发给对方,对方用同样的密钥解开。这个模式非常古老但极其高效,比如 AES-256-GCM,硬件加速后能跑几十 Gbps。
我在项目中遇到过一件事:一个同事用 AES-256-CBC 加密文件分块上传到对象存储,结果解密时老是报“bad decrypt”。查了半天,原来是 CBC 模式需要 IV(初始化向量),他没把 IV 存下来。你看,这种坑只要做过一次就记住了。
常见对称算法对比:
| 算法 | 密钥长度 | 模式 | 典型场景 |
|---|---|---|---|
| AES | 128 / 192 / 256 | GCM(认证加密) | 文件内容加密、流加密 |
| ChaCha20 | 256 | Poly1305 | 移动端、弱硬件 |
| DES(已弃用) | 56 | CBC | 遗留系统(千万别用) |
我的建议:对象存储加密上传时,优先选 AES-256-GCM。它自带认证标签,能同时保证机密性和完整性,省掉一个单独的 HMAC 步骤。
非对称加密 — 公钥私钥,安全分发密钥的神器
非对称加密,就是一个公钥一个私钥。公钥可以随便给别人,私钥自己藏着。你用公钥加密数据,只有对应的私钥才能解开。反过来,私钥签名,公钥验签。
我记得早期做 SDK 时,有人把 RSA 密钥对硬编码到源码里,然后传到 GitHub 公开仓库……后果可想而知。所以后来我们全面转向 ECC(椭圆曲线),比如 X25519 或 P-256,同样的安全强度下密钥更短,性能也更好。
| 特性 | RSA | ECC(如 P-256) |
|---|---|---|
| 密钥长度(安全强度128bit级) | 3072 位 | 256 位 |
| 加密性能 | 慢(特别是解密) | 快 3~10 倍 |
| 主用场景 | 兼容旧系统 | 现代 SDK、TLS 1.3 |
非对称加密在对象存储这儿的用法通常是:先随机生成一个临时对称密钥(数据密钥),用非对称加密的公钥把它包起来,再上传到对象存储的元数据里。下载时用私钥解开数据密钥,再用它去解密文件内容。这套叫“信封加密”,咱们后面的实践章节会详细做。
哈希函数 — 不可逆的指纹机
哈希函数,输入任意长的数据,输出固定长度的摘要(hash)。关键特性:不可逆、抗碰撞、雪崩效应(改一个 bit,摘要天差地别)。
你想想看,我们上传大文件到对象存储,怎么保证它在路上没被人改过?用哈希。客户端算一个 SHA-256,上传时带上。服务端下载后重新算一遍,对比一下。对不上?说明文件被篡改了。
我曾经踩过一个坑:用 MD5 做文件完整性校验。MD5 碰撞早就被攻破了,两个不同的文件能算出相同的 MD5。那一次因为是内部工具,我们没被发现,但从此以后我再也不敢用 MD5 做任何安全校验,一律用 SHA-256。
警告:永远不要用 MD5 或 SHA-1 做安全场景的哈希。现在推荐 SHA-256(64 字节)或 SHA-3。如果你需要用哈希做口令存储,记得加盐(salt)和慢哈希(如 bcrypt/Argon2)。
数字签名 — 哈希 + 非对称的组合拳
数字签名,本质上就是先用哈希函数给数据算个“指纹”,然后用私钥对这个指纹进行加密(签名)。验证时,用公钥解密签名得到原始指纹,再重新算数据的指纹比对。一样,就证明数据是私钥持有者签发的,而且没被篡改。
在对象存储 SDK 里,数字签名主要用来做“请求签名”。比如你往桶里上传文件,得用你的 SecretKey 把请求参数(时间戳、资源路径、请求体哈希)签名一下,服务端用你的 AccessKey 找到对应的公钥验签。这样就能确认请求是你发的,不是别人伪造的。
流程其实就三步:
- 客户端计算请求的哈希(一般是整个请求体的 SHA-256)。
- 用私钥(或 SecretKey)对哈希签名。有些 SDK 直接用 HMAC,也是对称签名方式。
- 服务端用公钥(或共享密钥)验签,通过则执行操作。
密钥管理服务 (KMS) 简介
密钥管理服务,简称 KMS,是帮你安全地生成、存储、轮换、使用密钥的云服务。AWS KMS、阿里云 KMS、Azure Key Vault 都属于这类产品。
为什么要用 KMS?
- 别把密钥硬编码到代码里。不用 KMS 的话,至少也得用环境变量或配置文件,但依然容易泄露。
- 集中管理密钥生命期:自动轮换、审计日志、访问控制。
- 加密操作远离应用:数据密钥的加密/解密在 KMS 内部完成,你的代码永远接触不到主密钥。
我自己的习惯是:在 SDK 里,所有需要加密上传的文件,先调 KMS 的 GenerateDataKey 接口拿到一个明文密钥和一个密文密钥。用明文密钥加密文件,然后把密文密钥作为对象元数据一起存到对象存储里。下载时先拿到密文密钥,调 KMS 的 Decrypt 解出明文密钥,再解密文件。整个过程,主密钥始终待在 KMS 里——安全多了。
一句话总结:对称加密管数据传输效率;非对称加密管密钥分发;哈希管完整性校验;数字签名管身份认证和防抵赖;KMS 管所有密钥的生命周期安全。这五个概念,就是对象存储加密上传下载 SDK 的底层基石。后面几章我们会把它们一个一个拼起来,做成真正的可运行代码。