一般用戶在數據庫中保存數據,雖然數據庫存儲的是二進制,無法直接明文打開查看,但是如果是一個外行人,直接連接進入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;
今天就介紹這些吧。