如果你想要血腥的細節繼續閱讀,否則所有我問的是,如果你可以限制什麼用戶能夠在他們的SQL語句上運行EXPLAIN命令,像GRANT解釋到比利會很好,但似乎並不存在。PostgreSQL限制誰可以執行解釋計劃
我的目標是加密列中的數據,對加密列進行索引,因爲它可用於搜索,並將加密密鑰隱藏於所有最終用戶(可與系統管理員或DBA共同見過)。在PostgreSQL中有哪些方法可以做到這一點?如果沒有辦法做到這一切,你有什麼樣的事情來試圖到達那裏?我下面列出的當前方法幾乎讓我在那裏,但是當解釋計劃在查詢上運行時,加密密鑰被暴露。這就是爲什麼我想知道是否可以限制用戶使用解釋的權限。
所以這裏是一個小小的設置來演示我在說什麼。 假設我在數據庫表的一列中加密了一些數據,則將通過gui前端屏幕或通過pg_admin即席查詢來搜索此列。
CREATE TABLE test(id serial,my_data TEXT);
--Fill table with enough data to need an index.
DO $$
DECLARE counter INTEGER := 0;
BEGIN
WHILE(counter < 1000)
LOOP
EXECUTE 'INSERT INTO test(my_data)
SELECT pgp_sym_encrypt(''avalue' || CAST(counter AS TEXT) || '''' || ', ''apasswordwithsomeentropy'',''compress-algo=1, cipher-algo=aes256'');';
counter := counter + 1;
END LOOP;
END$$;
ANALYZE test;
CREATE INDEX index1
ON test
USING btree
(my_data);
這個選擇仍然必須做一個全表掃描,我想避免。
SELECT id,
my_data,
pgp_sym_decrypt(cast(my_data as bytea),'apasswordwithsomeentropy')
FROM test
WHERE pgp_sym_decrypt(cast(my_data as bytea),'apasswordwithsomeentropy') = 'avalue114';
"Seq Scan on test (cost=0.00..665.00 rows=61 width=246)"
" Filter: (pgp_sym_decrypt((my_data)::bytea, 'apasswordwithsomeentropy'::text) = 'avalue114'::text)"
所以,如果我做什麼用的函數索引,以加快此查詢了。我使用get_password函數沒有使用密碼硬編碼創建索引。請記住,我不希望用戶查看索引定義並查看密碼。假設用戶不能從密碼中選擇或執行get_password(),只有具有額外特權的單個帳戶可以。而get_password()函數僅用於函數索引中。所以我的理解是用戶不需要執行該功能的權限?
CREATE TABLE password
(
password_id serial NOT NULL,
password_value text
);
INSERT INTO password(password_value)
SELECT 'apasswordwithsomeentropy';
from get_password();
CREATE FUNCTION get_password() RETURNS TEXT
AS 'select password_value
from password
where password_id = 1'
LANGUAGE SQL
IMMUTABLE;
CREATE INDEX index2 ON test (pgp_sym_decrypt(cast(my_data as bytea),get_password()));
現在,當我運行選擇數據庫使用索引2,我得到的結果很好,快速,因爲我想。問題是,當我對select查詢執行解釋計劃時,index2顯示平面文本中的密碼。
SELECT id,
my_data,
pgp_sym_decrypt(cast(my_data as bytea),'apasswordwithsomeentropy')
FROM test
WHERE pgp_sym_decrypt(cast(my_data as bytea),'apasswordwithsomeentropy') = 'avalue114';
"Bitmap Heap Scan on test (cost=4.73..171.49 rows=61 width=246)"
" Recheck Cond: (pgp_sym_decrypt((my_data)::bytea, 'apasswordwithsomeentropy'::text) = 'avalue114'::text)"
" -> Bitmap Index Scan on index2 (cost=0.00..4.72 rows=61 width=0)"
" Index Cond: (pgp_sym_decrypt((my_data)::bytea, 'apasswordwithsomeentropy'::text) = 'avalue114'::text)"
我唯一能想到的就是創建Web服務到數據庫,以防止用戶直接與數據庫交互。但作爲應用程序的內部,如果有些用戶有時仍然可以使用pg_admin,但不會看到諸如解釋計劃等所有內容,那將會很不錯。這些用戶不知道解釋計劃是什麼,也不會使用它們。
我不斷創建一個Web服務來包裝所有需要在通過Web服務調用的函數中運行的查詢,但這需要額外的時間才能在正式的開發環境中發佈並帶走廣告-hoc查詢方法並添加另一個層來維護。有任何想法嗎?由於
我不確定你在問什麼。索引一列加密數據有什麼好處?您必須解密列才能執行任何有意義的搜索。 – 2011-10-13 21:06:59
@Michael:不,不一定。如果您使用相同的算法,則不用解密該字段,而是加密搜索字符串 - 加密字段應與您的加密搜索字符串匹配。 – vol7ron
@ StarShip3000:我沒有閱讀你的整篇文章。根據您的字段的大小,您是否考慮過現有的散列算法(MD5/SHA),並閱讀了salting。 – vol7ron