对称密钥 vs 非对称密钥:选哪个?怎么选?
好,这一章咱们来聊聊 KMS 里最核心的基础概念——对称密钥和非对称密钥。说实话,很多刚接触 KMS 的同学会问:“不都是加密吗?分这么细干嘛?”嗯,我当时刚学 AWS KMS 时也这么想,直到有一次在生产环境上踩了坑……
密钥的类型决定了你能用它做什么、不能做什么,尤其是在跨账号共享的场景下。咱们先理清两者的本质区别,再聊怎么选。
对称密钥:一把钥匙开一把锁
对称密钥,顾名思义——加密和解密用的是同一个密钥。你想想看,就像你家大门钥匙,锁门和开门是同一把。
在 KMS 中,默认创建的 Customer Managed Key(CMK)就是对称密钥。使用流程很简单:
- 调用
GenerateDataKey或EncryptAPI,传入密钥 ID - KMS 用你指定的密钥进行加密,返回密文
- 解密时调用
DecryptAPI,传入同样的密文 - KMS 用同一份密钥材料解密
它的优势是速度快、性能好。我去年帮一个金融客户做数据湖加密,每天处理 TB 级数据,用对称密钥加密,延迟几乎可以忽略。但痛点也很明显——密钥必须安全传递,一旦泄露,所有数据都危险。
kms:Decrypt。
非对称密钥:公钥加密,私钥解密
非对称密钥是一对密钥:公钥(Public Key)和私钥(Private Key)。公钥可以公开分发,私钥必须保密。说白了,你用我的公钥加密,只有我能用私钥解密。
KMS 支持创建 RSA 和 ECC 类型的非对称密钥。你创建时选择密钥用途:ENCRYPT_DECRYPT 或 SIGN_VERIFY。
非对称密钥在跨账号共享时的优势很明显:你把公钥给目标账号,对方可以直接用公钥加密数据,然后把密文发回来,你再用自己的私钥解密。整个过程中,你的私钥从未离开过你的 AWS 账号,安全边界清晰。
关键差异对比
为了让你一目了然,我把最核心的差异整理成了一张表:
| 对比维度 | 对称密钥 | 非对称密钥 |
|---|---|---|
| 密钥数量 | 1 个(加解密共用) | 2 个(公钥 + 私钥) |
| 性能 | 极快(硬件加速可达 Gbps 级别) | 慢(RSA 2048 解密约 1-2ms) |
| 密钥分发 | 需要安全通道 | 公钥可明文公开 |
| 跨账号使用 | 只能通过 Grant/策略,且对方不能直接调用 Decrypt | 对方用公钥加密,你解密;也可以你签名,对方验签 |
| 典型用途 | 大量数据加密、S3 服务端加密、RDS 加密 | 数字签名、证书管理、跨账号加密传输 |
| KMS API 示例 | Encrypt / Decrypt |
Encrypt / Decrypt + GetPublicKey / Sign / Verify |
| 密钥轮换 | 自动轮换(每年一次)或手动 | 仅手动创建新密钥对 |
什么时候该用哪种?
我个人的判断原则很简单——
- 如果数据量很大,且加密解密都在一个账号内完成:无脑用对称密钥。性能好,编程接口简单。
- 如果需要在不同账号之间加密传输数据:非对称密钥更合适。你想想看,你不用给对方任何敏感权限,只需要导出公钥。
- 如果是数字签名/验签场景:必须用非对称密钥。对称密钥没法做签名,因为只有一把钥匙,你无法证明签名一定来自特定的人。
还有一个容易被忽略的点——密钥长度和算法。对称密钥现在 AWS 默认是 256 位 AES-GCM;非对称密钥支持 RSA 2048、3072、4096,以及 ECC P-256、P-384、P-521 和 secp256k1。ECC 的密钥更短但同样安全,性能也更好。
整体选择框架
下面这张图是我自己总结的决策流程,帮你快速定位:
实际案例:跨账号数据加密的两种姿势
场景一:用对称密钥 + Grant
你有一个对称密钥在账号 A,希望账号 B 能用它加密 S3 文件。我之前就是这么做的:
- 账号 A 创建 Grant,授权账号 B 的 IAM Role 使用
Encrypt - 账号 B 调用
kms:Encrypt时带上 Grant - 弊端:账号 B 不能解密,只能加密。解密必须由账号 A 来干
当时客户想实现“B 加密后,A 解密”的流程,用对称密钥的 Grant 方式确实可行,但每次调用都得传 Grant ,代码稍显啰嗦。
场景二:用非对称密钥 + 公钥导出
后来我换成了非对称密钥方案:
- 账号 A 创建 RSA 非对称密钥(用途:ENCRYPT_DECRYPT)
- 调用
GetPublicKey导出公钥(公钥本身是公开的) - 把公钥给账号 B(随便放 S3、Parameter Store 都行)
- 账号 B 用公钥加密敏感数据,得到 base64 密文
- 账号 B 把密文传给账号 A,账号 A 调用
Decrypt解密
这样账号 B 根本不需要任何 KMS 权限,完全不用配置密钥策略。代码也更清爽。
避坑指南
最后分享几个我在项目中踩过的坑:
- 坑一:我曾经以为对称密钥也能跨账号直接解密。结果发现 KMS 的
Decrypt只能在密钥所属账号内调用。跨账号解密必须用授权(Grant)或者让目标账号先调用ReEncrypt到自己账号的 CMK。 - 坑二:非对称密钥的公钥虽然可以导出,但注意公钥格式是 DER 编码的 SubjectPublicKeyInfo。如果你需要用 OpenSSL 加工,记得先转 PEM 格式。我的做法是用
openssl pkey -pubin -inform DER -outform PEM转换。 - 坑三:非对称密钥只支持
ENCRYPT_DECRYPT和SIGN_VERIFY两种用途,不能混用。创建时就选好,后面改不了。我见过有人创建了 RSA 签名密钥,然后想拿它加密,结果 API 直接报错。