加密技术基础:对称加密、非对称加密、哈希算法,在对象存储中的应用场景
做对象存储的加密 SDK,说白了就是在数据落地前给它上一把锁,取走的时候再打开。这把锁怎么设计、钥匙怎么管理,直接决定了你的系统安不安全、快不快。我最早接手这个模块时,还以为随便找个 AES 加密就完事了,后来发现完全不是那么回事。今天我把三种最核心的加密技术掰开揉碎讲清楚,顺便聊聊它们各自在对象存储里的“坑”和“巧”。
对称加密:数据层面的“贴身保镖”
对称加密大家都不陌生——加密和解密用同一把钥匙。像 AES、DES、SM4 都是常见的算法。在对象存储里,它主要负责保护数据本身。
应用场景:客户端把文件分块后,每一块用对称密钥加密,再上传到服务端。下载时用同一把密钥解密。整个过程密钥不出客户端,服务器拿到的是密文。
我个人习惯用 AES-256-GCM,因为它自带认证加密(AEAD),能同时保证机密性和完整性。我记得有一次项目用的是 AES-CBC,结果被 padding oracle 攻击打了个遍——嗯,从此我坚决不用 CBC 模式。
非对称加密:密钥管理的“外交官”
非对称加密有两把钥匙:公钥加密、私钥解密。RSA、ECC(椭圆曲线)是代表。它很慢,所以不适合直接加密大文件。在对象存储里,它主要用来解决对称密钥的传递问题。
应用场景:客户端生成一个随机的对称密钥(也叫数据密钥),然后用服务端的公钥加密这个对称密钥,上传到服务端。服务端用私钥解密得到对称密钥,再用来后续解密数据块。这叫“信封加密”(Envelope Encryption)。
我曾经踩过一个坑:直接用 RSA 加密整个文件,结果几千字节的文件加密了 5 秒——用户直接投诉。后来改用信封加密,每次只加密 32 字节的对称密钥,速度完全够用。
| 对比项 | 对称加密 | 非对称加密 | 哈希算法 |
|---|---|---|---|
| 密钥数量 | 1 个(对称密钥) | 2 个(公钥/私钥) | 无密钥 |
| 性能 | 快(GB/s 级别) | 慢(MB/s 级别) | 中等(取决于算法) |
| 主要用途 | 加密数据内容 | 加密对称密钥、签名 | 数据完整性校验 |
| 对象存储角色 | 数据落盘加密 | 密钥传输、身份认证 | 文件完整性、分片校验 |
| 典型算法 | AES-256、SM4 | RSA-2048、ECC P-256 | SHA-256、MD5 |
哈希算法:数据的“数字指纹”
哈希算法把任意长度的数据映射成固定长度的摘要,而且不可逆。SHA-256、MD5 是常见选择。在对象存储里,它主要用来做完整性校验。
应用场景:上传文件时,客户端计算出文件的 SHA-256 值,上传到服务端。服务端存储这个哈希作为元数据。下载文件时,客户端重新计算哈希,对比服务端返回的值——如果一致说明文件没被篡改或损坏。这就是“端到端完整性校验”。
你可能觉得这不是废话吗?但现实中有个尴尬的问题:服务端提供的哈希(比如 ETag)未必是文件内容的哈希,可能是服务端自己分块拼接的。我遇到过一家对象存储厂商,它的 ETag 是分块哈希的 Hex 拼接——结果客户自己算的跟它算的总对不上。后来我们统一要求服务端也暴露 content-md5 字段,才算解决。
另外,哈希还能用在分片上传中。比如一个 1GB 的文件分成 100 个分片,每个分片都有独立的 SHA-256。上传完成后,服务端把这些分片哈希组成一棵 Merkle 树——根哈希就是整个文件的摘要。这样你下载任意分片时都能独立验证。
上图把三种加密在上传和下载两个方向的配合关系画清楚了。你可以看到:上传时先算哈希(完整性)、再对称加密(机密性)、最后非对称加密密钥(密钥安全)。下载时反过来执行,最后一步重新算哈希做完整性校验——这样就构成了一个闭环。
实际编码中要留意的点
- 算法选择:对称加密首选 AES-256-GCM,别用 ECB/CBC。非对称加密,如果是密钥封装,用 RSA-OAEP 或 ECIES;如果是签名,用 ECDSA。哈希至少用 SHA-256,MD5 只适合做分片标识,不适合安全校验。
- 密钥生命周期:数据密钥用完即弃,不要复用。每次上传生成新的随机对称密钥。主密钥(非对称私钥)要定期轮转,存硬件安全模块(HSM)或 KMS。
- 分片大小:对称加密的分片大小建议 16KB~1MB,太大会导致内存占用高,太小会引入过多加解密开销。
- 元数据安全:哈希值虽然不可逆,但也要当作敏感数据对待,别让未授权的人拿到——否则他可以对比哈希来暴力猜测文件内容。
好了,这部分的内容就到这里。三种加密技术说到底就是:对称加密干重活、非对称加密管钥匙、哈希算法做质检。你是用 C++ 还是 Go 还是 Java 写 SDK,道理都一样。