zoukankan      html  css  js  c++  java
  • 简单为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;

    今天就介绍这些吧。

  • 相关阅读:
    简明python_Day2_字典、集合、模块、类、编程习惯
    测试2T2
    测试2T1
    bzoj2761
    一元三次方程求根公式及韦达定理
    状压DP入门——铺砖块
    高精度模板
    测试1T3
    测试1T2
    测试1T1
  • 原文地址:https://www.cnblogs.com/chenfool/p/12335768.html
Copyright © 2011-2022 走看看