1 目的
有些业务场景,数据库中的敏感数据
需要存储为密文形式
,这里使用mysql内置加密函数
对数据进行加密。
2 加密算法
对称加密算法:AES
加密后数据转换为:十六进制
3 内置函数说明
函数 | 说明 |
---|---|
AES_ENCRYPT(字符串,秘钥) | 加密函数 |
AES_DECRYPT(字符串,秘钥) | 解密函数 |
HEX(二进制字符串) | 二进制转十六进制 |
UNHEX(十六进制字符串) | 十六进制转 二进制 |
4 加密、解密入口
自定义mysql函数
。使用自定义函数进行加密和解密,当前需要更改算法
的时候,只需要更改自定义函数即可。
如果数据库要求
不能自定义函数
,或者考虑对数据库性能的影响
,可以在JAVA代码环节
进行加密、解密的数据处理。
5 自定义加密、解密函数
5.1 加密函数
(1)函数定义
CREATE FUNCTION `ext_encrypt`(`info` varchar(100),`seacrt_key` varchar(20)) RETURNS varchar(100) CHARSET utf8
BEGIN
RETURN HEX(AES_ENCRYPT(info,seacrt_key));
END
(2)使用
# 密钥为123456
# 加密结果为:6379779C5A736CAD203C4DD3D0A3CE7C
select ext_encrypt('abcd测试123','123456');
(3)场景
插入数据、更新数据
5.2 解密函数
(1)函数定义
CREATE FUNCTION `ext_decrypt`(`info` varchar(100),`seacrt_key` varchar(20)) RETURNS varchar(100) CHARSET utf8
BEGIN
RETURN AES_DECRYPT(UNHEX(info),seacrt_key);
END
(2)使用
# 密钥为123456
# 解密密结果为:abcd测试123
select ext_decrypt('6379779C5A736CAD203C4DD3D0A3CE7C','123456');
(3)场景
返回查询结果、组装查询条件
6 说明
6.1 对加密后结果进行进制转换
为什么使用AES+HEX
组合的方式,将加密后的数据转换为16进制后再存储,不直接存储加密后的数据
?
因为:AES加密后的数据为二进制
,不可读,不便于查询出来后作为中间数据
进行存储处理。因此将加密后的二进制数据转换为16进制后再进行存储。
直接用AES进行加密,结果如下:
# AES加密结果:cyw�Zsl� <M�У�|
select AES_ENCRYPT('abcd测试123','123456');
6.2 关于HEX的长度
加密后得到的密文,通过HEX函数转换为16进制后,会导致存储的数据长度比原始数据长很多
,浪费存储空间
。
这里可以考虑使用base32
和base64
,将二进制转换为32位或64位
,会大大减少转换后的字符串长度,减少对于数据库存储空间的浪费。
这里以转换为64进制为例:
(1)加密
# 加密,结果:Y3l3nFpzbK0gPE3T0KPOfA==
select TO_BASE64(AES_ENCRYPT('abcd测试123','123456'));
(2)解密
# 解密,结果:abcd测试123
select AES_DECRYPT(FROM_BASE64('Y3l3nFpzbK0gPE3T0KPOfA=='),'123456');
可见,同样的数据加密后,转换为不同进制,结果的长度不一样。
进制 | 转换后结果 |
---|---|
16进制HEX | 6379779C5A736CAD203C4DD3D0A3CE7C |
64进制BASE64 | Y3l3nFpzbK0gPE3T0KPOfA== |
如果从存储空间
考虑,建议转换为64进制
,两个进制转换上对于服务器性能
和加密速度
上有一定的区别,可以自行测试。
网友评论