标准的base64加密主要是为了二进制字符在网络传输中的可靠性和兼容性,并不是严格意义的加密。 在我目前遇到场景中,要求有一种加密效率高,而且加密稳定,安全性较高 的方案,综合评估之后,选择借鉴base64的实现方式,并加以改进,使之成为一种可定义的加密方案。
- 加解密效率高
- 密文可逆
- 加密稳定,相同的字符,相同的码表,相同的密文,则保证密文始终一致
- 加密码表可自定义,保证安全性
- 多因子加密进一步保证安全性
- 使用简便
- 因为加密稳定性,大数据集样本碰撞可导致码表和密码被破解
- 因为加密方式,密文会比原文增长一倍
- 使用数据库本身提供的加解密方法,但这种方式效率较低,对模糊查询不友好,不能使用索引
- 在代码中加密后再存入,目前大多数使用不可逆的hash加密后存储,可逆的加密方案较少,我的方案也属于这一类
- 使用密文索引,实施难度高
- 加解密都是在代码中进行,然后传输给数据库进行存储,可保证传输数据安全性,且码表和密码都存储在代码配置中,就算数据被拦截也不可破解
- 模糊匹配的友好,因为加密稳定性,相同的字符在同一套码表和密码中始终可得到相同的密文,所以查询时直接无需解密,直接使用密文就可进行模糊匹配
- 可利用索引,因为加密后都是纯字符,所以字段可使用索引,且索引效率更高
- 字符长度是原文的一倍,所以需要字段长度设置需要更长,空间存储也需要更多
- 密文字符增长会导致网络传输消耗大于原文字符传输
go get github.com/oliverCJ/crypt
参见example文件中的实例
- 加密方式:4位切分加密
- 密码:0
- 左码表:"ABCDEFGHIJKLMNOP"
- 右码表:"ABCDEFGHIJKLMNOP"
- 备注:两个码表完全相同的话,等同于一个码表
待加密字符串 | 加密后字符串 | 备注 |
---|---|---|
f | GG | |
f1 | GGDB | |
中 | OELIKN | |
** | OELIKNOFJLLN | |
**人民 | OELIKNOFJLLNOELKLKOGLAJB | |
中a | OELIKNGB | |
a国 | GBOFJLLN | |
中a国 | OELIKNGBOFJLLN |
从加密后的效果来看,相同的字符在不同的字符串组合中,也是相同的加密结果。满足我们的稳定性要求。
- 测试环境:macos 64位,CPU:2.4G i9 8核, 内存:32G
- 加密方式:4位切分
字符长度 | 测试时长(秒) | 执行次数 | 结果 |
---|---|---|---|
1 | 1 | 50000000 | 26 ns/op |
1 | 3 | 200000000 | 26 ns/op |
50 | 1 | 5000000 | 315 ns/op |
50 | 3 | 20000000 | 320 ns/op |
200 | 1 | 1000000 | 1090 ns/op |
200 | 3 | 5000000 | 1101 ns/op |
4位切分方式双码表被当作左右表使用,所以性能上的差异基本耗在做异或操作中。 由测试结果来看,除开系统本身的消耗,综合测算每个加密字符加密耗时在5-7ns左右
- 测试环境:macos 64位,CPU:2.4G i9 8核, 内存:32G
- 加密方式:4位切分
密文长度 | 测试时长(秒) | 执行次数 | 结果 |
---|---|---|---|
2 | 1 | 100000000 | 19 ns/op |
2 | 3 | 200000000 | 19 ns/op |
54 | 1 | 20000000 | 75 ns/op |
54 | 3 | 50000000 | 75 ns/op |
300 | 1 | 5000000 | 237 ns/op |
300 | 3 | 20000000 | 238 ns/op |
解密效率高于加密,因为解密的操作更简单。 综合测算每2个字符解密耗时在0.5-1.5ns左右