创建非对称密钥:RSA/ECC密钥对创建、签名验证场景、密钥用途限制
非对称密钥,说白了就是“一对钥匙”——公钥可以公开,私钥必须保密。在 KMS 里,创建非对称密钥并不是简单的一句 aws kms create-key 就完事了。你选算法、定用途、考虑场景,每一步都有讲究。
我今天跟你聊聊怎么在 KMS 里创建 RSA 和 ECC 密钥对,什么时候用签名,什么时候用加密,以及那些容易踩的坑。
先搞清楚:非对称密钥的两种“人设”
KMS 的非对称密钥有两大用途:
- 加密/解密 —— 用公钥加密,私钥解密。适合少量数据或作为信封加密的密钥封装。
- 签名/验证 —— 用私钥签名,公钥验证。适合代码签名、文档验真、身份认证。
关键限制:一个非对称密钥一旦创建,用途就固定了。你不能拿一个加密用的密钥去签名,反过来也不行。
KeyUsage 为 ENCRYPT_DECRYPT 或 SIGN_VERIFY。选错了只能删除重建。
创建 RSA 密钥对:经典但开销大
RSA 在非对称加密里是元老,兼容性好。但它的私钥运算很慢,密钥越长越慢。
- 选择密钥规格:RSA_2048、RSA_3072、RSA_4096。4096 更安全,但性能消耗也翻倍。我一般推荐 RSA_2048 用于加密,RSA_3072 用于签名(因为签名需要更高安全余量)。
- 指定用途:若用于加密,
KeyUsage=ENCRYPT_DECRYPT;若用于签名,KeyUsage=SIGN_VERIFY。 - 执行创建:AWS CLI 示例
# 创建一个RSA_2048加密密钥
aws kms create-key \
--key-usage ENCRYPT_DECRYPT \
--key-spec RSA_2048 \
--description "RSA 2048 for envelope encryption"
# 创建一个RSA_3072签名密钥
aws kms create-key \
--key-usage SIGN_VERIFY \
--key-spec RSA_3072 \
--description "RSA 3072 for code signing"
返回的 KeyId 就是你的非对称密钥 ID。注意:KMS 不会直接给你私钥明文,私钥永远留在 KMS 里。你需要的是公钥,可以通过 get-public-key 拿到。
创建 ECC 密钥对:轻快但算法多
ECC 在同等安全强度下,密钥更短、运算更快。KMS 支持多种椭圆曲线:
| 密钥规格 | 安全强度(等效RSA) | 典型用途 |
|---|---|---|
| ECC_NIST_P256 | RSA-3072 左右 | 签名验证 |
| ECC_NIST_P384 | RSA-7680 左右 | 高安全签名 |
| ECC_NIST_P521 | RSA-15360 左右 | 最高安全签名 |
| ECC_SECG_P256K1 | 与P256相当 | 区块链/比特币签名 |
| SM2 | 国密标准 | 中国合规场景 |
创建命令和 RSA 类似,只是 --key-spec 换成 ECC 规格:
# 创建P256签名密钥
aws kms create-key \
--key-usage SIGN_VERIFY \
--key-spec ECC_NIST_P256 \
--description "ECC P256 for JWT signing"
# 注意:ECC密钥目前只支持SIGN_VERIFY,不支持加密/解密
# 如果你试图用ECC做加密,KMS会直接报错
密钥用途限制:你选对了吗?
KMS 对非对称密钥的用途限制非常严格。一张表说清楚:
| KeyUsage 值 | 支持的操作 | 典型密钥规格 | 注意事项 |
|---|---|---|---|
ENCRYPT_DECRYPT |
加密、解密 | RSA_2048, RSA_3072, RSA_4096, SM2 | 数据最大不超过 4096 字节(RSA 密钥长度决定) |
SIGN_VERIFY |
签名、验证 | RSA_2048+, ECC 系列, SM2 | ECC 只能签名,不可加密;RSA 签名和加密可以分开创建 |
ENCRYPT_DECRYPT + SIGN_VERIFY |
❌ 不支持 | — | 不能同时使用,创建时必须二选一 |
签名验证场景实战:代码签名流程
假设你用 ECC P256 密钥给一段消息签名,外部伙伴用你的公钥验证。我手写一个伪流程:
- 创建签名密钥(已完成)
- 获取公钥
- 客户端签名(消息摘要)
- 服务器验证
# 获取公钥并导出
aws kms get-public-key \
--key-id 1234abcd-12ab-34cd-56ef-1234567890ab \
--output json | jq -r '.PublicKey' | base64 -d > my_public_key.der
# 签名
aws kms sign \
--key-id 1234abcd-12ab-34cd-56ef-1234567890ab \
--message "Hello, KMS!" \
--message-type RAW \
--signing-algorithm ECDSA_SHA_256 \
--output text --query Signature | base64 -d > signature.bin
# 验证(通常由另一方执行)
aws kms verify \
--key-id 1234abcd-12ab-34cd-56ef-1234567890ab \
--message "Hello, KMS!" \
--message-type RAW \
--signing-algorithm ECDSA_SHA_256 \
--signature fileb://signature.bin
避坑指南:我曾经犯过一个低级错误——在签名时用了 --message 直接传十六进制值,结果 KMS 认为那是原始字节,验证时怎么都对不上。正确的做法是统一用 raw bytes,或者指定 --message-type DIGEST 并自己计算哈希。建议新手一律用 RAW 模式,让 KMS 帮你处理摘要。
核心逻辑图:非对称密钥从创建到使用
下面这张图把整个流程串起来,你一看就明白。
看到没?创建密钥时你就得想清楚最终场景。加密路径只有 RSA(或 SM2),签名路径 RSA 和 ECC 都行。个人建议:如果是微服务间的令牌签名,选 ECC P256;如果是传统加密数据,选 RSA 2048。
几点额外提醒
- 密钥轮换:非对称密钥也支持自动轮换(仅对称密钥自动轮换?不对,KMS 非对称密钥不支持自动轮换,需手动创建新密钥并迁移引用)。这个我们在后面章节细讲。
- 跨区域问题:非对称密钥跨区域使用时,你得在目标区域也创建同名密钥(或使用 AWS KMS Multi-Region Keys)。我曾在一次全球部署中吃了亏——忘了在东京区域创建密钥,结果签名验证全部超时。
- 成本:非对称密钥比对称密钥贵不少,按调用次数计费。没事别频繁调用
Encrypt或Sign,能用对称密钥做信封加密的场景尽量用对称。
KeyId、用途、创建日期记在一个安全 note 里。半年后再看,自己都忘了哪个密钥是干嘛用的。人嘛,金鱼记忆。