不少朋友詢問如何加密PostgreSQL的存儲過程,作了一個簡單示例。目前考慮,一種加密方式是使用C語言編譯成庫文件,缺點是維護起來比較麻煩,優勢是速度很是快。另一種是將存儲過程以密文存儲,使 pg_proc系統表中的 prosrc 不可讀,編寫起來比較麻煩,好處是一勞永逸。 git
密文存儲過程也能夠有兩種實現方式,一種是建立函數時將函數轉換成密文,這種方式若是不修改內核,沒法直接在建立時生成,好在做爲開源軟件的一大好處,這個咱們是能夠作到的,本次不對此進行討論。另外一種使用外部程序在建立以前將代碼轉換成密文,而後正常使用CREATE FUNCTION建立,這個須要作的是建立一個新的過程語言引擎。 sql
EnterpriseDB已經有相似實現:
http://www.enterprisedb.com/docs/en/9.0/oracompat/Postgres_Plus_Advanced_Server_Oracle_Compatibility_Guide-195.htm 安全
Oracle的實現:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/wrap.htm oracle
個人實現是很簡陋的,只能算程序可行性證實,若是想用在生產環境,還須要更多加強:
一、加密只是簡單的字母調換,只支持ASCII碼;
二、密文是一次性轉換並保存在內存中,容易經過其它方式讀出來。若是改爲流加密,一邊解密一邊編譯,把編譯過的部分清掉,還能提升安全性;
三、報錯信息沒有修改,若是有編譯錯誤,報錯時會把一些源代碼帶出來;
四、只能加密函數體部分,所有轉換須要修改內核語法解析部分(就像EDB所作的);
五、沒有準備Windows平臺,只有Linux; app
源代碼代碼下載連接:
http://url.cn/M1ka7U
由前幾天的git分支改寫,包含PL/pgSQL源代碼目錄用來作比較。
ide
一、pl_wrap srcfile [outfile]
srcfile裏只包含函數體部分,輸出加密後的密文
二、建立存儲過程語言模板
INSERT INTO pg_pltemplate values('plpgwrappedsql',true,true,
'plpgwrappedsql_call_handler',null,'plpgwrappedsql_validator', '$libdir/plpgwrappedsql', null);
三、建立過程語言
CREATE LANGUAGE plpgwrappedsql;
四、建立函數
CREATE FUNCTION func_name() RETURNS type AS
$$
<<密文過程>>
$$
LANGUAGE plpgwrappedsql;
函數