简单为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;

 

 

今天就介绍这些吧。

 

posted @ 2020-02-20 15:46  chenfool  阅读(4006)  评论(0编辑  收藏  举报