1. 概述

1.1 背景

基于 KMS 集成设计 的讨论与测试反馈:

  • 在 aes、sm4、hmac 中接入 KMS 导致 CLI 参数复杂度过高(需区分 key/iv 来源、解密时传入 encrypted_dek、考虑 key_id 绑定等)
  • 范围收缩仅在 envelope 命令中接入 KMS
  • 输出优化:在单信封概念下,将业务密文与密钥密文分离,以 JSON 输出
  • 算法扩展:支持多种对称加密算法

1.2 目标

  • 信封命令支持 KMS(wrap_key_type: RSA | KMS)
  • 输出格式:默认 JSON,业务密文与 encrypted_dek 分离;可选 blob 保持向后兼容
  • 对称算法扩展:AES-256-GCM、SM4-GCM、ChaCha20-Poly1305
  • 新增 list-algorithms 子命令,便于查看支持的算法类型

2. mode 与 wrap_key_type

2.1 模式选择

envelope 命令必须显式指定 mode,通过 --mode 参数:

mode默认说明
local本地模式,使用 RSA 公钥/私钥
kms-KMS 模式,使用云 KMS 生成/解密 DEK

默认:--mode local

使用 KMS 时必须指定 --mode kms

2.2 wrap_key_type

常量说明
0x01WRAP_RSA本地 RSA 公钥加密 DEK
0x02WRAP_KMS云端 KMS 生成 DEK

KMS 模式:DEK 由用户输入的对称密钥 ID(--kms-key-id)通过 KMS GenerateDataKey 生成。


3. 对称算法扩展

3.1 支持的算法

algo_id算法名密钥长度Nonce 长度Tag 长度
0x01aes-256-gcm321216
0x02sm4-gcm161216
0x03chacha20-poly1305321216

3.2 选择方式

通过 --symmetric-algo 指定,取值:aes-256-gcmsm4-gcmchacha20-poly1305


4. 输出格式

4.1 格式选项

选项格式默认
--format jsonJSON,业务密文与 encrypted_dek 分离✅ 默认
--format blob单一二进制 blob向后兼容

4.2 JSON 格式结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
  "metadata": {
    "operation": "encrypt",
    "algorithm": "envelope",
    "input": { "type": "text", "size": 5 },
    "parameters": {
      "symmetric_algo": "aes-256-gcm",
      "wrap_key_type": "rsa",
      "request_id": "uuid"
    }
  },
  "result": {
    "ciphertext": "base64(业务密文)",
    "encrypted_dek": "base64(密钥密文)",
    "nonce": "base64(12字节)",
    "aad": "base64或字符串",
    "plaintext_binding": "base64(32字节)",
    "symmetric_algo": "aes-256-gcm",
    "wrap_key_type": "rsa",
    "eet_version": "2.3.x",
    "request_id": "uuid"
  },
  "runtime": {
    "request_id": "eet-uuid",
    "timestamp": "...",
    "duration_ms": 123,
    "kms_calls": []
  }
}

约束ciphertextencrypted_dek 等必须为密文(base64 编码),不得为明文。

4.3 blob 格式(向后兼容)

ENVELOPE_FORMAT_SPEC.md 定义的二进制格式一致,用于兼容旧版及管道场景。


5. list-algorithms 子命令

5.1 用法

1
eet envelope list-algorithms

5.2 输出内容

列出三类支持项:

类别说明示例值
wrap_key_typeDEK 封装方式rsa, kms
kms_backendKMS 厂商(仅 wrap_key_type=kms 时相关)aws, azure, gcp
symmetric_algo对称加密算法aes-256-gcm, sm4-gcm, chacha20-poly1305

5.3 输出示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "wrap_key_types": [
    { "id": "rsa", "description": "Local RSA public key encrypts DEK" },
    { "id": "kms", "description": "Cloud KMS generates DEK" }
  ],
  "kms_backends": ["aws", "aliyun", "huawei", "azure"],
  "symmetric_algos": [
    { "id": "aes-256-gcm", "key_len": 32, "nonce_len": 12 },
    { "id": "sm4-gcm", "key_len": 16, "nonce_len": 12 },
    { "id": "chacha20-poly1305", "key_len": 32, "nonce_len": 12 }
  ]
}

6. CLI 参数设计

6.1 mode 与参数互斥

mode加密必选解密必选互斥
local-f 公钥-f 私钥--kms-* 互斥
kms--kms-backend--kms-key-id--kms-region--kms-backend--kms-region-f 互斥

KMS 解密--kms-key-id 不必选。encrypted_dek(KMS ciphertext blob)中通常已含密钥引用,KMS Decrypt 可仅凭 blob 与 region 解密。

6.2 加密

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 本地模式(默认)
eet envelope encrypt --mode local -f pub.pem -i "data" --symmetric-algo aes-256-gcm

# KMS 模式:必须 key_id、region;输出含 encrypted_dek
eet envelope encrypt --mode kms --kms-backend aws --kms-key-id arn:aws:kms:... --kms-region cn-north-1 \
  -i "data" --symmetric-algo aes-256-gcm

# 输出格式
eet envelope encrypt -f pub.pem -i "data" --format json   # 默认
eet envelope encrypt -f pub.pem -i "data" --format blob   # 向后兼容

6.3 解密

1
2
3
4
5
6
# 本地模式
eet envelope decrypt --mode local -f priv.pem -i envelope.json -o plain.txt

# KMS 模式:必须 region;key_id 不必选;encrypted_dek 从信封解析
eet envelope decrypt --mode kms --kms-backend aws --kms-region cn-north-1 \
  -i envelope.json -o plain.txt

6.4 参数汇总

参数加密解密说明
--modelocal(默认)local(默认)local | kms
-flocal 时必选local 时必选公钥/私钥文件路径
--kms-backendkms 时必选kms 时必选aws、aliyun、huawei、azure
--kms-key-idkms 时必选kms 时不必选对称密钥 ID(加密时 DEK 由此生成)
--kms-regionkms 时必选kms 时必选区域
--symmetric-algo--默认 aes-256-gcm
--format--json(默认)、blob

7. 其他细化点

7.1 参数校验

场景校验
--mode local 且未指定 -f报错:-f required when mode is local
--mode kms 且 encrypt 时缺少 --kms-key-id--kms-region报错:--kms-key-id and --kms-region required when mode is kms (encrypt)
--mode kms 且 decrypt 时缺少 --kms-region报错:--kms-region required when mode is kms (decrypt)
--mode local 且指定了 --kms-*报错:--kms-* not allowed when mode is local
--mode kms 且指定了 -f报错:-f not allowed when mode is kms

7.2 解密输入格式检测

  • 输入 -i 可为 JSON 字符串或文件路径
  • 自动检测:若内容以 { 开头则按 JSON 解析;否则按 base64 解码,若为 EET magic 则按 blob 解析
  • 解析后根据 wrap_key_type 校验:若 mode 与 envelope 不一致(如 mode=local 但 envelope 为 kms),报错提示

7.3 输出约定

  • 加密 KMS:输出中必须包含 encrypted_dek(DEK 密文),位于 JSON 的 result.encrypted_dek 或 blob 的 enc_dek 字段
  • 解密 KMS:encrypted_dek 从信封(JSON 或 blob)中解析,无需用户单独传入

7.4 其他默认与可选

默认/说明
--symmetric-algo默认 aes-256-gcm
--format默认 json
--aad沿用现有默认(如 CipherHUB 兼容值)
--kms-endpoint可选,私有化时覆盖
-p / --password本地模式私钥密码(解密时)

7.5 KMS 调用轨迹

  • 成功与失败均输出 runtime.kms_calls,含 request_id、step、api、status(见 KMS 设计 3.1.2 节)

8. 向后兼容

场景兼容策略
旧 blob 解密支持 blob 输入,自动检测 format
新 JSON 解密解析 JSON 中 ciphertext、encrypted_dek 等字段
默认行为默认 --format json,旧脚本可显式指定 --format blob

9. 与 KMS 设计的关系

  • 仅 envelope 接入 KMS,aes、sm4、hmac 不接入
  • KMS 相关参数、endpoint 默认值、request_id 输出等沿用 KMS_INTEGRATION_DESIGN.md
  • 信封 KMS 的 DEK 由 KMS GenerateDataKey 生成,请求长度 = 密钥长度 + Nonce 长度(见 KMS 设计 3.1.1 节)

10. 实现步骤概要

  1. 新增 list-algorithms 子命令
  2. 增加 --mode 参数(local | kms,默认 local),实现 mode 与 -f/--kms-* 互斥校验
  3. 扩展 algo_id 枚举,实现 SM4-GCM、ChaCha20-Poly1305
  4. 增加 --symmetric-algo--format 参数
  5. 实现 JSON 格式输出(ciphertext、encrypted_dek 分离)
  6. 集成 KMS(wrap_key_type=0x02):加密必选 key_id+region,解密必选 region、key_id 不必选
  7. 解密时支持 JSON 与 blob 两种输入格式,自动检测