AES和DES
对于存储在数据库中的敏感信息,往往需要对其进行加密。MySql提供了多种加密方式,其中两种为AES和DES。
这两种方式用法类似。性能上,AES各方面都略强于DES。因此推荐使用AES。
AES加密
MySql提供了2个AES加密与解密的函数:
AES_ENCRYPT('明文', 'key') // 加密
AES_DECRYPT('明文', 'key') // 解密
其中:
- 加密函数为
AES_ENCRYPT()
,其原理是使用密钥key
对明文进行加密,返回一个二进制字符串。这就是加密内容。 - 解密函数为
AES_DECRYPT()
,其原理是使用密钥key
对密文进行解密,返回明文内容。
于是,尽管数据库中存储的密文信息是可逆的,但必须知道密钥才能解密。
由于AES_ENCRYPT()
返回的是二进制字符串,因此对于要进行加密的字段,需要设置其数据类型为varbinary。
若将字段的数据类型设置为varchar,则在做字符转换的时或空格被删除时可能会有问题。此时使用的一个方案是调用MySql的HEX()
将密文十六进制化再存入。对应地,取出时需要用UNHEX()
将密文进行反十六进制化。
实例
设有表格user,有3个字段:id,name,password。其中password字段需要加密存储。
下面采用的密钥为coco。
直接加密存储
将password字段的数据类型设置为varbinary。
插入数据时调用AES_ENCRYPT()
加密:
INSERT INTO user
VALUES (1, '张三', AES_ENCRYPT(('123456'), 'coco'))
获取数据时调用AES_DECRYPT()
解密:
SELECT id, name, AES_DECRYPT(password, 'coco') as password
FROM user
WHERE id=1
该种方式更加高效,推荐。
将密文十六进制化
将password字段的数据类型设置为varchar。
插入数据时调用AES_ENCRYPT()
加密,然后调用HEX()
将密文十六进制化:
INSERT INTO user
VALUES (1, '张三', HEX(AES_ENCRYPT(('123456'), 'coco')))
获取数据时先调用UNHEX()
,再调用AES_DECRYPT()
解密:
SELECT id, name, AES_DECRYPT(UNHEX(password), 'coco') as password
FROM user
WHERE id=1
该种方式效率低一点。除非必须将字段类型定义为varchar,否则推荐使用直接加密存储方式。
其他
两种加密方式都支持中文。
但由于加密后整个字符串就全变成了密文,因此对于该字段的查询只能是完全匹配,无法模糊查询。
另外,由于这是MySql提供的函数,因此在Spring框架中开发时直接写在对应的SQL语句中即可。