文章目录
- 一、分类总览
- 二、加密能力基础
- 三、单一密钥加解密类
- [四、基础 Keyset 管理类](#四、基础 Keyset 管理类)
- 五、KMS封装Keyset管理类
- 六、增强加解密类
- 七、最容易混淆的函数对比
- 八、常用案例
- 九、使用注意事项
- 十、参考资料
一、分类总览
1、函数分类
| 分类 | 主要解决的问题 | 代表函数 |
|---|---|---|
| 1、单一密钥加解密类 | 使用单一 BINARY 密钥直接加密、解密字段 |
SYM_ENCRYPT、SYM_DECRYPT |
| 2、基础 Keyset 管理类 | 创建、追加、查看、恢复和轮转 Keyset | NEW_KEYSET、ADD_KEY_TO_KEYSET、KEYSET_TO_JSON、KEYSET_FROM_JSON、ROTATE_KEYSET |
| 3、KMS 封装 Keyset 管理类 | 使用 KMS 对 Keyset 再加密,并支持重新封装、轮转和使用 | NEW_WRAPPED_KEYSET、REWRAP_KEYSET、ROTATE_WRAPPED_KEYSET、USE_WRAPPED_KEYSET |
| 4、增强加解密类 | 使用基础 Keyset 或封装 Keyset 对业务数据加密、解密 | ENHANCED_SYM_ENCRYPT、ENHANCED_SYM_DECRYPT |
2、全部函数
| 分类 | 函数 | 功能 |
|---|---|---|
| 1、单一密钥加解密类 | SYM_ENCRYPT |
对指定列做随机性加密,返回 BINARY 密文 |
| 1、单一密钥加解密类 | SYM_DECRYPT |
对已随机加密的数据解密,返回 BINARY 明文 |
| 2、基础 Keyset 管理类 | NEW_KEYSET |
按指定算法创建新的 Keyset |
| 2、基础 Keyset 管理类 | ADD_KEY_TO_KEYSET |
向已有 Keyset 添加密钥,并设置为主密钥 |
| 2、基础 Keyset 管理类 | KEYSET_TO_JSON |
将 BINARY Keyset 转成可读 JSON |
| 2、基础 Keyset 管理类 | KEYSET_FROM_JSON |
将 JSON Keyset 转回 BINARY |
| 2、基础 Keyset 管理类 | ROTATE_KEYSET |
自动生成新密钥并将其设置为主密钥 |
| 3、KMS 封装 Keyset 管理类 | NEW_WRAPPED_KEYSET |
使用 KMS 创建封装 Keyset |
| 3、KMS 封装 Keyset 管理类 | REWRAP_KEYSET |
使用新的 KMS 密钥重新封装 Keyset |
| 3、KMS 封装 Keyset 管理类 | ROTATE_WRAPPED_KEYSET |
重新封装 Keyset,同时支持更新数据密钥算法 |
| 3、KMS 封装 Keyset 管理类 | USE_WRAPPED_KEYSET |
将封装 Keyset 转换为可供加解密函数使用的基础 Keyset |
| 4、增强加解密类 | ENHANCED_SYM_ENCRYPT |
使用指定 Keyset 加密数据 |
| 4、增强加解密类 | ENHANCED_SYM_DECRYPT |
使用与加密时一致的 Keyset 解密数据 |
二、加密能力基础
| 模式 | 密钥管理方式 | 适用场景 |
|---|---|---|
| 单一密钥 | 用户自行保存一个密钥 | 简单字段随机加密 |
| 基础 Keyset | 一个 Keyset 中可维护多个数据密钥 | 需要密钥轮转 |
| KMS 封装 Keyset | KMS 密钥再次加密 Keyset | 对密钥安全要求更高 |
1、定义
MaxCompute 的加密能力可以分成三层:
- 单一密钥:直接传入一个
BINARY密钥。 - 基础 Keyset:由 MaxCompute 管理一组数据密钥。
- KMS 封装 Keyset:再使用 KMS 对 Keyset 进行封装保护。
2、区别
| 对比 | 区别 |
|---|---|
| 单一密钥 vs Keyset | 一个密钥 vs 一组可轮转密钥 |
| 基础 Keyset vs 封装 Keyset | Keyset 本身直接保存 vs 再由 KMS 密钥保护 |
SYM_* vs ENHANCED_SYM_* |
直接传单一密钥 vs 使用 Keyset |
AES-GCM-256 |
随机性加密,相同明文多次加密结果可以不同 |
AES-SIV-CMAC-* |
Keyset 支持的另一类密钥算法 |
3、简单记忆
简单字段加密:
SYM_ENCRYPT / SYM_DECRYPT。多密钥管理:Keyset。
更安全的 Keyset 管理:KMS Wrapped Keyset。
Keyset 加解密业务数据:
ENHANCED_SYM_*。
4、案例
sql
-- 使用扩展数据类型前开启 MaxCompute 2.0 数据类型
SET odps.sql.type.system.odps2=true;
三、单一密钥加解密类
| 函数 | 功能 |
|---|---|
SYM_ENCRYPT |
对指定列做随机性加密,返回 BINARY 密文 |
SYM_DECRYPT |
对已随机加密的数据解密,返回 BINARY 明文 |
1、定义
SYM_ENCRYPT:使用一个BINARY密钥对STRING或BINARY明文进行随机性加密。SYM_DECRYPT:使用相同密钥和相同加密模式解密BINARY密文。
当前支持的加密模式包括 AES-GCM-256,密钥长度为 256 bits。
2、区别
| 对比 | 区别 |
|---|---|
SYM_ENCRYPT |
明文 → 密文 |
SYM_DECRYPT |
密文 → 明文 |
| 输入 | 加密支持 STRING / BINARY;解密输入为 BINARY |
| 输出 | 两者都返回 BINARY |
| AAD | 加密时用了 AAD,解密时必须使用相同 AAD |
随机性加密的特点:
相同明文、相同密钥,多次加密得到的密文也可能不同。
3、简单记忆
ENCRYPT= 加密。
DECRYPT= 解密。密钥和 AAD 要前后一致。
4、案例
sql
-- 加密:结果为 BINARY,通常再 BASE64 方便存储
SELECT BASE64(
SYM_ENCRYPT(
'0001',
CAST('b75585cf321cdcad42451690cdb7bfc4' AS BINARY)
)
) AS encrypted_value;
-- 解密:结果转回 STRING
SELECT CAST(
SYM_DECRYPT(
UNBASE64(encrypted_value),
CAST('b75585cf321cdcad42451690cdb7bfc4' AS BINARY)
) AS STRING
) AS plain_value
FROM source_table;
四、基础 Keyset 管理类
| 函数 | 功能 |
|---|---|
NEW_KEYSET |
按指定算法创建新的 Keyset |
ADD_KEY_TO_KEYSET |
向 Keyset 新增密钥 |
KEYSET_TO_JSON |
Keyset 转 JSON |
KEYSET_FROM_JSON |
JSON 转 Keyset |
ROTATE_KEYSET |
自动生成并切换主密钥 |
1、定义
Keyset 是一个可保存多个数据密钥的密钥集合。
支持的主要算法类型包括:
AES-GCM-256AES-SIV-CMAC-128AES-SIV-CMAC-256
2、区别
| 函数 | 作用 |
|---|---|
NEW_KEYSET |
从零创建 Keyset |
ADD_KEY_TO_KEYSET |
手工加入指定密钥 |
ROTATE_KEYSET |
系统自动生成新密钥并设为主密钥 |
KEYSET_TO_JSON |
主要用于查看 Keyset 内容 |
KEYSET_FROM_JSON |
将 JSON 表示恢复成可用 Keyset |
ADD_KEY_TO_KEYSET 与 ROTATE_KEYSET:
前者由用户提供
raw_key。后者由系统自动生成新密钥。
3、简单记忆
NEW= 新建。
ADD= 手工加密钥。
ROTATE= 自动轮转。
TO_JSON= 查看。
FROM_JSON= 恢复。
4、案例
sql
-- 创建 Keyset
SELECT HEX(
NEW_KEYSET('AES-GCM-256', 'user info key')
) AS keyset_hex;
-- 增加密钥并设为主密钥
SELECT HEX(
ADD_KEY_TO_KEYSET(
UNHEX(keyset_hex),
'AES-SIV-CMAC-128',
UNHEX('b75585cf321cdcad42451690cdb7bfc49c26092f60f854e72d43244c55620a3d'),
'new key'
)
) AS new_keyset_hex
FROM key_table;
-- Keyset 转 JSON
SELECT KEYSET_TO_JSON(UNHEX(keyset_hex))
FROM key_table;
-- JSON 转回 Keyset
SELECT HEX(KEYSET_FROM_JSON(json_keyset))
FROM key_table;
-- 自动轮转主密钥
SELECT HEX(
ROTATE_KEYSET(
UNHEX(keyset_hex),
'AES-SIV-CMAC-256',
'rotate key'
)
)
FROM key_table;
五、KMS封装Keyset管理类
| 函数 | 功能 |
|---|---|
NEW_WRAPPED_KEYSET |
创建 KMS 封装 Keyset |
REWRAP_KEYSET |
使用新 KMS 密钥重新封装 |
ROTATE_WRAPPED_KEYSET |
重新封装并轮转数据密钥 |
USE_WRAPPED_KEYSET |
将封装 Keyset 转为加解密可用形式 |
1、定义
KMS 封装 Keyset 的核心思路:
数据由 Keyset 中的数据密钥加密;Keyset 本身再由 KMS 用户主密钥保护。
这样无需直接查看或保存原始数据加密密钥。
2、区别
| 函数 | 核心作用 |
|---|---|
NEW_WRAPPED_KEYSET |
第一次创建封装 Keyset |
REWRAP_KEYSET |
更换外层 KMS 密钥 |
ROTATE_WRAPPED_KEYSET |
不仅重新封装,还能更新内部数据密钥算法 |
USE_WRAPPED_KEYSET |
解封装为后续加解密函数可使用的 Keyset |
REWRAP_KEYSET vs ROTATE_WRAPPED_KEYSET:
REWRAP主要改变外层 KMS 封装。
ROTATE_WRAPPED还可以更新数据密钥算法。
3、简单记忆
NEW_WRAPPED= 创建封装密钥集。
REWRAP= 换外包装。
ROTATE_WRAPPED= 换包装 + 轮换里面的密钥。
USE_WRAPPED= 解开后拿来使用。
4、案例
sql
-- 创建封装 Keyset
SELECT HEX(
NEW_WRAPPED_KEYSET(
'acs:kms:cn-hangzhou:<UserId>:key/<CmkId>',
'acs:ram::<UserId>:role/kms',
'AES-GCM-256',
'user info key'
)
) AS wrapped_keyset;
-- 使用新 KMS 密钥重新封装
SELECT HEX(
REWRAP_KEYSET(
'acs:kms:cn-hangzhou:<UserId>:key/<NewCmkId>',
'acs:ram::<UserId>:role/kms',
UNHEX(wrapped_keyset)
)
)
FROM key_table;
-- 重新封装并轮转数据密钥
SELECT HEX(
ROTATE_WRAPPED_KEYSET(
'acs:kms:cn-hangzhou:<UserId>:key/<CmkId>',
'acs:ram::<UserId>:role/kms',
UNHEX(wrapped_keyset),
'AES-GCM-256',
'rotate key'
)
)
FROM key_table;
-- 获取可用于加解密的基础 Keyset
SELECT USE_WRAPPED_KEYSET(
'acs:kms:cn-hangzhou:<UserId>:key/<CmkId>',
'acs:ram::<UserId>:role/kms',
UNHEX(wrapped_keyset)
)
FROM key_table;
六、增强加解密类
| 函数 | 功能 |
|---|---|
ENHANCED_SYM_ENCRYPT |
使用指定 Keyset 加密数据 |
ENHANCED_SYM_DECRYPT |
使用与加密时一致的 Keyset 解密数据 |
1、定义
增强加解密函数使用 Keyset,而不是直接传入单个原始密钥。
ENHANCED_SYM_ENCRYPT:Keyset + 明文 →BINARY密文。ENHANCED_SYM_DECRYPT:同一 Keyset + 密文 →BINARY明文。
Keyset 可以来自:
NEW_KEYSETUSE_WRAPPED_KEYSET
2、区别
| 对比 | 区别 |
|---|---|
SYM_ENCRYPT |
直接传单一密钥 |
ENHANCED_SYM_ENCRYPT |
传 Keyset |
SYM_DECRYPT |
单一密钥解密 |
ENHANCED_SYM_DECRYPT |
Keyset 解密 |
| 基础 Keyset | 可直接作为参数 |
| 封装 Keyset | 通常先通过 USE_WRAPPED_KEYSET 获取可使用形式 |
3、简单记忆
SYM_*= 单密钥。
ENHANCED_SYM_*= Keyset。Wrapped Keyset 先
USE,再加解密。
4、案例
sql
-- 使用基础 Keyset 加密
SELECT BASE64(
ENHANCED_SYM_ENCRYPT(
UNHEX(keyset_hex),
'0001'
)
) AS encrypted_value
FROM key_table;
-- 使用基础 Keyset 解密
SELECT CAST(
ENHANCED_SYM_DECRYPT(
UNHEX(keyset_hex),
UNBASE64(encrypted_value)
) AS STRING
) AS plain_value
FROM source_table;
七、最容易混淆的函数对比
| 函数组合 | 最核心区别 |
|---|---|
SYM_ENCRYPT vs ENHANCED_SYM_ENCRYPT |
单一密钥 vs Keyset |
SYM_DECRYPT vs ENHANCED_SYM_DECRYPT |
单一密钥解密 vs Keyset 解密 |
NEW_KEYSET vs NEW_WRAPPED_KEYSET |
基础 Keyset vs KMS 封装 Keyset |
ADD_KEY_TO_KEYSET vs ROTATE_KEYSET |
手工加入密钥 vs 系统自动生成并轮转 |
KEYSET_TO_JSON vs KEYSET_FROM_JSON |
Keyset→JSON vs JSON→Keyset |
REWRAP_KEYSET vs ROTATE_WRAPPED_KEYSET |
更换 KMS 封装 vs 更换封装并轮转数据密钥 |
NEW_WRAPPED_KEYSET vs USE_WRAPPED_KEYSET |
创建封装 Keyset vs 使用封装 Keyset |
BASE64 vs HEX |
都可把二进制变成可存储字符串,但编码方式不同 |
AES-GCM-256 vs AES-SIV-CMAC-* |
不同加密算法类型 |
八、常用案例
1、身份证字段加密后存储
sql
SELECT
id,
BASE64(
SYM_ENCRYPT(
id_card_no,
CAST('b75585cf321cdcad42451690cdb7bfc4' AS BINARY)
)
) AS id_card_no_encrypt
FROM user_info;
2、解密后返回STRING
sql
SELECT
CAST(
SYM_DECRYPT(
UNBASE64(id_card_no_encrypt),
CAST('b75585cf321cdcad42451690cdb7bfc4' AS BINARY)
) AS STRING
) AS id_card_no
FROM user_info;
3、创建Keyset
sql
SELECT HEX(
NEW_KEYSET('AES-GCM-256', 'user info')
) AS keyset_hex;
4、轮转Keyset
sql
SELECT HEX(
ROTATE_KEYSET(
UNHEX(keyset_hex),
'AES-GCM-256',
'2026 rotate'
)
)
FROM key_table;
5、查看Keyset详情
sql
SELECT KEYSET_TO_JSON(
UNHEX(keyset_hex)
)
FROM key_table;
6、使用Keyset加密
sql
SELECT BASE64(
ENHANCED_SYM_ENCRYPT(
UNHEX(keyset_hex),
id_card_no
)
) AS encrypted_value
FROM user_info
CROSS JOIN key_table;
九、使用注意事项
1、定义
加密函数涉及密钥、BINARY 类型、KMS 权限以及数据解密能力,需要比普通 SQL 函数更关注安全和权限管理。
2、区别
主要注意:
- 使用
BINARY等扩展类型时,可先开启:
SET odps.sql.type.system.odps2=true; - 单一密钥方案中,密钥需要用户自行安全保存。
- 密钥丢失后可能导致密文无法恢复。
- 不建议将明文密钥直接写在长期保存或共享的 SQL 中。
- 官方建议可将密钥保存在受控表中,并通过权限控制和安全视图隔离密钥。
- KMS 封装 Keyset 需要提前配置 KMS、RAM 角色及 MaxCompute 访问权限。
- 加密和解密时使用的 Keyset / AAD 必须匹配。
3、简单记忆
密钥不要散落在 SQL。
加密前先规划密钥保存和轮转。
解密权限要比查询密文权限更严格。
高安全要求优先考虑 KMS 封装 Keyset。
4、案例
sql
-- 开启 MaxCompute 2.0 类型系统
SET odps.sql.type.system.odps2=true;
十、参考资料
阿里云 MaxCompute 官方文档:
https://help.aliyun.com/zh/maxcompute/encryption-and-decryption-functions