一般用户在数据库中保存数据,虽然数据库存储的是二进制,无法直接明文打开查看,但是如果是一个外行人,直接连接进入mysql中,还是可以直接查看数据的。
所以对于一些核心数据,特别是企业重要数据资产,一般会再增加一个透明加密的数据安全保护,以避免一些无关人员直接获取重要信息。
在O记里,就有专门的透明加密的功能模块,叫做Oracle Key Manager,感兴趣的童鞋可以去研究一下。
众所周知,mysql 在互联网里使用得非常多,除了它的性能确实不错外,免费也是一个重要原因。但是免费就代表着不讲究,对于一些重要的企业功能,它没有,你也不能够说啥,毕竟O记也为大家提供商业版本。
所以在MySQL 中,是不具备透明加密功能的。虽然如此,但是mysql 具备加密/解密的基础功能啊,还有函数和触发器,无论环境多么恶劣,只要想做成一件事,总有方法来实现,人民群众是历史的创造者。
---- 分割线 ----
首先为了避免加密 和 解密的 key 直接暴露,我们先创造一张表来保存这个key 值。
--配置一个保存 加/解 密 key 的表,并且提前准备一个key 值
create table tkey (keyname varchar(100));insert into tkey values ('sequoiadb');
创建一张测试表,避免后面的触发器无法创建
--测试表,验证加密和解密效果
drop table if existstest;create table test (id int, name varchar(100));
创建insert 和 update 的触发器,触发器只针对 test.name 字段进行加密保存,对 test.id 字段不做处理。如果大家在业务里想做得更加复杂,肯定需要包装一层配置方式,这里只介绍如何实现
--insert的 触发器,只针对 test.name 字段进行加密保存
drop trigger if existst_insert;
DELIMITER ;;create triggert_insert
beforeinsert ontestforeach rowbegin
select keyname into @key_name from tkey limit 1;set new.name = hex(AES_ENCRYPT(new.name, @key_name));end;;
DELIMITER ;--update 触发器,只针对 test.name 字段进行加密更新
drop trigger if existst_update;
DELIMITER ;;create triggert_update
beforeupdate ontestforeach rowbegin
select keyname into @key_name from tkey limit 1;set new.name = hex(AES_ENCRYPT(new.name, @key_name));end;;
DELIMITER ;
创建一个解密的函数,主要是为了在查询时,更加友好
--解密 函数
drop function if existsdecrypt;
DELIMITER ;;create function decrypt(col varchar(100))returns varchar(100) DETERMINISTICBEGIN
select keyname into @key_name from tkey limit 1;return AES_DECRYPT(unhex(col), @key_name);END;;
DELIMITER ;
这样就基本配置好了mysql 的透明加密和 解密动作了,我们来验证一下
--验证sql,可以通过普通查询和解密查询,看看数据是否真的被自动加密了
truncate tabletest;insert into test values (1,'sdb');insert into test values (2, 'sequoiadb');--普通查询,得到的结果是一堆乱码
select * fromtest;--解密查询,返回预期结果
select id, decrypt(name) fromtest;update test set name = 'jushan' where id = 1;--解密查询
select id, decrypt(name) from test where id = 1;
我自己测试的结果截图:
*** 分割线 ***
上面的例子是结合了触发器和函数,对于复杂的业务系统,可能会在运维时造成影响,所以这里再提供一个只使用函数的方式,实现数据的加密和解密
创建 密钥表
create table tkey (keyname varchar(100));insert into tkey values ('sequoiadb');
创建 测试表
create table test (id int, name varchar(100));
创建加密函数(encrypt名称和已有函数冲突,所以用了 encrypt_new)
DELIMITER ;;create function encrypt_new(col varchar(100))returns varchar(100) DETERMINISTICbegin
select keyname into @key_name from tkey limit 1;return hex(AES_ENCRYPT(col, @key_name));end;;
DELIMITER ;
创建解密函数
DELIMITER ;;create function decrypt_new(col varchar(100))returns varchar(100) DETERMINISTICBEGIN
select keyname into @key_name from tkey limit 1;return AES_DECRYPT(unhex(col), @key_name);END;;
DELIMITER ;
测试
truncate tabletest;insert into test values (1, encrypt_new('abc'));select * fromtest;select id, decrypt_new(name) from test;
今天就介绍这些吧。