3. 加密算法与数据类型的关联
好,咱们直接聊正题。加密算法不是万能的,它对数据类型有自己的脾气。你选错算法,轻则解密失败,重则丢数据。我在项目里见过太多这种事了。今天我就把三种主流算法的数据类型适配问题掰开揉碎了讲。
3.1 对称加密:AES 与 SM4 的二进制游戏
对称加密,说白了就是一把钥匙开一把锁。AES 和 SM4 都是块加密算法,它们操作的是固定长度的二进制数据块。你想想看,要加密的字段可能是文本、数字、甚至是一张图片的二进制流。这些数据怎么喂给算法?
关键点一:输入必须是字节序列
AES 和 SM4 不认“字符串”或“整数”。它们只认 byte[] 。所以每次加密前,你得先把原始数据序列化成字节。我习惯用一个通用函数,根据字段类型做转换:
// 示例:数据类型到字节数组的转换
public byte[] toBytes(Object fieldValue) {
if (fieldValue instanceof String) {
return ((String) fieldValue).getBytes(StandardCharsets.UTF_8);
} else if (fieldValue instanceof Integer) {
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
buffer.putInt((Integer) fieldValue);
return buffer.array();
} else if (fieldValue instanceof byte[]) {
return (byte[]) fieldValue;
}
// 其他类型...
}
关键点二:块对齐与填充
AES 块大小固定 16 字节,SM4 也是 16 字节。如果你的数据不是 16 的倍数,就必须填充。填充方式有很多种,我最常用 PKCS7。嗯,这里要注意,填充会使密文比明文长。如果你存储字段长度有严格限制,得提前算好。
不同类型的字段,加密后的长度增长也不同。我整理了一个常用表:
| 原始数据类型 | 原始字节长度 | AES-256 加密后长度 | SM4 加密后长度 |
|---|---|---|---|
| String (10 字符, UTF-8) | 30 字节 | 32 字节 | 32 字节 |
| Integer | 4 字节 | 16 字节 | 16 字节 |
| Long | 8 字节 | 16 字节 | 16 字节 |
| Boolean | 1 字节 | 16 字节 | 16 字节 |
你看,对于小字段,加密后的膨胀率很高。所以你在设计库表结构时,密文字段长度要留够余量。
3.2 非对称加密:RSA 与 SM2 的天花板
非对称加密有个硬伤——数据长度限制。这个限制从哪来?RSA 和 SM2 的加密过程基于大数运算。你输入的数据,必须小于模数(N)的字节长度。一旦超过,算法就报错。
RSA 的限制:
- RSA-2048 的模数 N 是 256 字节。但还需要预留填充空间(OAEP 或 PKCS#1 v1.5)。
- 实际可加密的最大字节数 = 密钥字节长度 - 填充开销 - 1(OAEP 填充时,最多可加密 190 字节)。
- 明文超过限制,只能分段加密。但这会大幅降低性能,且需要额外管理分段逻辑。
SM2 的限制:
- SM2 基于椭圆曲线,它的限制不是模数长度,而是曲线参数。
- SM2 公钥加密的明文长度上限是曲线阶的字节数,通常是 32 字节左右。
- 所以 SM2 几乎不能直接加密大数据块。它更常用来加密对称密钥。
我把常用的适配规则列一下,方便你对照:
| 非对称算法 | 密钥长度 | 最大明文长度(OAEP) | 推荐适配场景 |
|---|---|---|---|
| RSA-2048 | 256 字节 | 190 字节 | 加密短字符串、数字签名、对称密钥的加密 |
| RSA-4096 | 512 字节 | 446 字节 | 同上,可处理稍长数据 |
| SM2 | 256 位(等效) | 约 64 字节 | 密钥交换、数字签名、加密对称密钥 |
3.3 哈希算法:单向输出的风格
哈希不是加密,它是摘要。它把任意长度的输入,映射成固定长度的输出。你想想看,一个 1GB 的视频和一个 1 字节的字符,经过 SHA-256 处理后,都变成 32 字节的哈希值。这个特性对字段级加密来说,意义重大。
输入特征:几乎无限制
SHA-256、SM3、MD5 这些算法,接受任意长度的二进制数据。你不用操心块对齐和填充。但要注意,输入数据内容哪怕只改动一个比特,输出哈希值就会面目全非。这就是所谓的雪崩效应。
输出特征:固定长度、不可逆
哈希输出长度是固定的。我列几个常见的:
- MD5: 16 字节(128 位),但现在已不安全。
- SHA-256: 32 字节(256 位),国密场景经常用。
- SM3: 32 字节(256 位),国密标准,与 SHA-256 长度一致。
- SHA-512: 64 字节(512 位),安全性更高,但计算更慢。
哈希还有一个特性叫“输入不敏感”。意思是,你不能从哈希值反推原始数据。所以它只能用于校验,不能用于“解密”。这一点很多新手会搞混。记得有一次,同事试图用哈希值做登录验证的“密码”,还要我帮他实现“解密功能”……那是不可能的。
3.4 核心知识体系总览
为了让你一眼看清这三类算法的数据适配关系,我画了一张图。它把算法类型、数据输入限制、输出特征串起来了。你多看几遍,心里就有谱了。
记住这张图。对称加密适合大数据块,但要处理好字节序列和填充。非对称加密适合小数据或密钥交换,千万不能超长。哈希算法最适合做完整性校验和脱敏。这三种算法配合起来,才能适配你字段里复杂的业务数据类型。