简单为mysql 实现透明加密方法
一般用户在数据库中保存数据,虽然数据库存储的是二进制,无法直接明文打开查看,但是如果是一个外行人,直接连接进入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 exists test; create table test (id int, name varchar(100));
创建insert 和 update 的触发器,触发器只针对 test.name 字段进行加密保存,对 test.id 字段不做处理。如果大家在业务里想做得更加复杂,肯定需要包装一层配置方式,这里只介绍如何实现
-- insert的 触发器,只针对 test.name 字段进行加密保存 drop trigger if exists t_insert; DELIMITER ;; create trigger t_insert before insert on test for each row begin 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 exists t_update; DELIMITER ;; create trigger t_update before update on test for each row begin select keyname into @key_name from tkey limit 1; set new.name = hex(AES_ENCRYPT(new.name, @key_name)); end ;; DELIMITER ;
创建一个解密的函数,主要是为了在查询时,更加友好
-- 解密 函数 drop function if exists decrypt; DELIMITER ;; create function decrypt(col varchar(100)) returns varchar(100) DETERMINISTIC BEGIN select keyname into @key_name from tkey limit 1; return AES_DECRYPT(unhex(col), @key_name); END ;; DELIMITER ;
这样就基本配置好了mysql 的透明加密和 解密动作了,我们来验证一下
-- 验证sql,可以通过普通查询和解密查询,看看数据是否真的被自动加密了 truncate table test; insert into test values (1,'sdb'); insert into test values (2, 'sequoiadb'); -- 普通查询,得到的结果是一堆乱码 select * from test; -- 解密查询,返回预期结果 select id, decrypt(name) from test; 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) DETERMINISTIC begin 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) DETERMINISTIC BEGIN select keyname into @key_name from tkey limit 1; return AES_DECRYPT(unhex(col), @key_name); END ;; DELIMITER ;
- 测试
truncate table test; insert into test values (1, encrypt_new('abc')); select * from test; select id, decrypt_new(name) from test;
今天就介绍这些吧。
再进击