1. 简介

信封加密(Envelope Encryption)是一种混合加密方式:使用 RSA 公钥加密随机生成的对称密钥(DEK),再用该密钥对实际数据进行 AES-256-GCM 加密。适用于大数据加密、密钥托管等场景。

特点:

  • 单一信封格式:加密输出为一个 base64 字符串或文件,解密只需私钥 + 信封
  • 支持大文件:对称加密高效,RSA 仅加密 32 字节 DEK
  • 安全设计:OAEP-SHA256、结构校验、明文绑定,无 Padding Oracle 风险

2. 前置条件

2.1 密钥要求

  • 公钥:RSA 2048、3072 或 4096 位,PEM 格式
  • 私钥:与公钥配对的 RSA 私钥,可带密码保护

2.2 生成密钥对

1
2
3
4
5
6
7
8
# 生成 RSA 2048 位密钥对(默认)
eet rsa generate -f my_key -s 2048 -p 1234567890

# 生成 RSA 3072 位
eet rsa generate -f my_key -s 3072 -p 1234567890

# 生成带密码保护的私钥
eet rsa generate -f my_key -s 2048 -p "your_password"

生成后得到 my_key_rsa_public.pemmy_key_rsa_private.pem

3. 加密

3.1 基本用法

1
2
3
4
5
# 加密文本,输出到 stdout(默认 JSON 格式)
eet envelope encrypt -f pub.pem -i "hello"

# 仅输出 base64 信封(便于管道)
eet envelope encrypt -f pub.pem -i "hello" --raw

QQ_1771684687696

QQ_1771684749133

3.2 输入方式

方式选项说明
明文默认-i 为 UTF-8 字符串
Base64-e-i 为 base64 编码的二进制数据
文件--from-file-i 为文件路径
1
2
3
4
5
6
7
8
9
# 明文
eet envelope encrypt -f pub.pem -i "敏感数据"

# Base64 二进制输入
B64=$(echo -n "binary" | base64)
eet envelope encrypt -f pub.pem -i "$B64" -e --raw

# 文件加密(必须指定 -o)
eet envelope encrypt -f pub.pem -i data.bin --from-file -o data.env

3.3 输出方式

方式选项说明
stdout默认输出 JSON,含 envelope 字段
文件-o path二进制信封写入文件
Raw--raw仅输出 base64 信封,便于管道
1
2
3
4
5
6
7
8
# 输出到文件
eet envelope encrypt -f pub.pem -i "secret" -o secret.env

# 管道到文件
eet envelope encrypt -f pub.pem -i "secret" --raw > secret.env

# 禁止覆盖已存在文件
eet envelope encrypt -f pub.pem -i "secret" -o out.env --no-force

3.4 可选参数

选项默认值说明
--aadCipherHUB 默认GCM 附加认证数据,加解密需一致
-l64非文件输入时的最大大小(MB)
1
2
# 自定义 AAD(加解密需相同)
eet envelope encrypt -f pub.pem -i "data" --aad "my-context-001"

4. 解密

4.1 基本用法

1
2
3
4
5
6
# 从 base64 字符串解密
ENV=$(eet envelope encrypt -f pub.pem -i "hello" --raw)
eet envelope decrypt -f priv.pem -i "$ENV" --raw

# 从文件解密
eet envelope decrypt -f priv.pem -i secret.env --from-file -o plain.txt

4.2 输入方式

方式选项说明
Base64默认-i 为 base64 编码的信封
文件--from-file-i 为信封文件路径

4.3 私钥密码

1
2
3
4
5
# 无密码私钥
eet envelope decrypt -f priv.pem -i "$ENV" -o plain.txt

# 有密码私钥
eet envelope decrypt -f priv.pem -p "your_password" -i secret.env -o plain.txt

4.4 错误提示

解密失败时统一返回:

1
Decryption failed: invalid envelope or wrong key.

不区分具体失败原因(密钥错误、信封损坏、格式错误等),以避免信息泄露。

5. 典型场景

5.1 文本加密存储

1
2
3
4
5
6
# 加密
eet envelope encrypt -f recipient_pub.pem -i "机密内容" -o message.env

# 解密(收件人用私钥)
eet envelope decrypt -f recipient_priv.pem -i message.env --from-file -o message.txt
cat message.txt

5.2 文件加密备份

1
2
3
4
5
# 加密大文件
eet envelope encrypt -f backup_key.pem -i /path/to/sensitive.db --from-file -o backup.db.env

# 解密恢复
eet envelope decrypt -f backup_key.pem -i backup.db.env --from-file -o restored.db

5.3 管道串联

1
2
3
4
5
# 加密后 base64 存入变量
SECRET=$(eet envelope encrypt -f pub.pem -i "pipeline data" --raw)

# 解密并继续处理
eet envelope decrypt -f priv.pem -i "$SECRET" --raw | base64 -d | your_tool

5.4 与 JSON 解析配合

1
2
3
4
5
# 提取 envelope 字段
ENV=$(eet envelope encrypt -f pub.pem -i "data" --json | jq -r '.result.envelope')

# 解密
eet envelope decrypt -f priv.pem -i "$ENV" --raw

6. 输出格式

6.1 默认(Pretty JSON)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "metadata": {
    "operation": "encrypt",
    "algorithm": "envelope",
    "input": { "type": "text", "size": 5 },
    "parameters": { "key_size": 2048, "request_id": "uuid" }
  },
  "result": { "envelope": "RUVUAQEBBnYyLjMu..." },
  "runtime": { "request_id": "...", "timestamp": "...", "version": "v2.x.x" }
}

6.2 全局输出选项

选项说明
--raw仅输出主结果(envelope 或 plain)
--json单行 JSON
--pretty-json彩色格式化 JSON(默认)

7. 注意事项

  1. 密钥规格:当前仅支持 RSA 2048/3072/4096,其他规格会报错
  2. AAD 一致性:加解密需使用相同 AAD,否则 GCM 校验失败
  3. 文件加密:使用 --from-file 时必须指定 -o 输出文件
  4. 互斥选项-e(base64)与 --from-file 不能同时使用
  5. 信封完整性:信封内含结构校验,篡改或截断会导致解密失败

8. KMS 模式与凭据配置

使用 --mode kms 时,DEK 由云 KMS 生成/解密,需先安装 KMS 扩展并配置对应云厂商的凭据。

8.1 安装 KMS 扩展

1
pip install easy_encryption_tool[kms]

8.2 KMS 凭据配置

不同 KMS 后端需配置各自的凭据,eet 通过各云厂商的标准 SDK 读取,不通过 CLI 参数传入敏感信息。

AWS KMS(--kms-backend aws

支持以下任一方式配置 AWS 凭据:

方式说明
环境变量AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY;可选 AWS_DEFAULT_REGIONAWS_REGION
配置文件~/.aws/credentials~/.aws/config
IAM RoleEC2/ECS/Lambda 等环境中自动使用实例角色
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 方式一:环境变量
export AWS_ACCESS_KEY_ID="your_access_key"
export AWS_SECRET_ACCESS_KEY="your_secret_key"
export AWS_DEFAULT_REGION="us-east-1"

# 方式二:配置文件 ~/.aws/credentials
# [default]
# aws_access_key_id = your_access_key
# aws_secret_access_key = your_secret_key
#
# ~/.aws/config
# [default]
# region = us-east-1

密钥 ID 格式arn:aws:kms:region:account:key/key-id 或短格式 key-idalias/alias-name

其他 KMS 后端(预留)

后续若支持阿里云、华为云、Azure 等,将补充对应凭据配置说明,结构类似:

  • 环境变量或配置文件
  • 区域/endpoint 参数
  • 密钥 ID 格式

8.3 KMS 模式示例

1
2
3
4
5
6
7
8
# 加密(需 --kms-key-id、--kms-region)
eet envelope encrypt --mode kms --kms-backend aws \
  --kms-key-id arn:aws:kms:us-east-1:123456789:key/xxx \
  --kms-region us-east-1 -i "data"

# 解密(--kms-key-id 可选,encrypted_dek 中含密钥引用)
eet envelope decrypt --mode kms --kms-backend aws --kms-region us-east-1 \
  -i envelope.json --from-file -o plain.txt

8.4 自定义 Endpoint

私有化或专有云部署时,可通过 --kms-endpoint 覆盖默认 endpoint:

1
2
3
eet envelope encrypt --mode kms --kms-backend aws \
  --kms-key-id key-id --kms-region custom \
  --kms-endpoint https://kms.internal.example.com -i "data"