簡單為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;

 

 

今天就介紹這些吧。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM