2014-01-20 25 views
1

例如,在Django中有這樣做的回購:https://sourcegraph.com/github.com/dcwatson/django-pgcrypto如何在SQLAlchemy中使用pgcrypt實現列級PostgresSQL加密?

有一個在SQLAlchemy的手冊一些討論,但我使用非字節列:http://docs.sqlalchemy.org/en/rel_0_9/core/types.html

我使用的SQLAlchemy在Heroku上運行的燒瓶中。

一個代碼示例和/或一些討論將不勝感激。

+0

每當你考慮加密時,你不能將「如何」與「爲什麼」分開。你的目標是什麼?你試圖保護什麼,從誰那裏*? –

+0

主要目的是在數據庫備份「被盜」或數據庫文件本身從服務器「被盜」的情況下,對這些列具有基本的加密保護。我希望這可以在不增加太多代碼複雜度的情況下實現,同時避免錯誤加密過程無意中破壞數據的風險。 – Soferio

回答

4

有這類決策的一堆階段,它不只是「推插件進棧和加密的事情是照顧」

首先,你真的需要爲每列分類它對攻擊者的吸引力&什麼搜索/查詢需要使用它,無論是連接列/候選索引等。一些數據需要比其他數據更強大的保護。

考慮一下你要保護誰:

  • 休閒攻擊者(用於遠程表的拷貝,例如SQL注入孔)
  • 偷來的數據庫備份(提示:加密這些太)
  • 被盜/泄露日誌文件,可能包括查詢和參數
  • 帶有直接非超級用戶SQL級別訪問的攻擊者
  • 攻擊者直接超級用戶SQL級別的訪問
  • 攻擊誰獲得了「Postgres的」 OS用戶直接訪問,這樣他們就可以修改配置,複製/編輯日誌,安裝惡意擴展,改變功能定義等等
  • 攻擊誰在數據庫服務器上獲得根

當然,也有應用程序服務器,上游妥協編程語言和工具包的可信源,等等。最終,你達到了一個點,你必須說「我不能切實防禦這一點「。你不能防止有人進來,說:「我來自政府,除非你允許我在這個客戶的服務器上安裝rootkit,否則我會爲你做x/y/z」。關鍵是你必須決定你的做什麼必須防範,並基於此做出安全決策。

一個很好的折衷辦法可能是在應用程序中儘可能多地使用加密,所以PostgreSQL從不會看到加密/解密密鑰。儘可能使用單向散列,而不是使用可逆加密,並且當你散列時,正確地散列你的散列

這意味着pgcrypto實際上並沒有太大的好處,因爲您永遠不會向服務器發送純文本,也不會將密鑰材料發送到服務器。

這也意味着對於列SecretValue具有相同明文的兩個人對於數據庫中的SecretValueSalt, SecretValueHashedBytes具有完全不同的值。所以你不能加入它,在WHERE子句中有用地使用它,有用地索引它,等等。

出於這個原因,你會經常危及安全。您可以對數據的一部分進行無損哈希,以便獲得部分匹配,然後將所有結果提取到您的應用程序,並在需要完整信息的應用程序端進行過濾。所以您的SecretValue存儲現在看起來像SecretValueFirst10DigitsUnsaltedHash, SecretValueHashSalt, SecretValueHashBytes。但更好的列名稱。

如果有疑問,只是不要發送對數據庫敏感的任何明文。這意味着pgcrypto對你來說沒有多大用處,你會主要做應用程序端加密。 #1的原因是,如果您發送明文(或更糟糕的是,密鑰材料)到數據庫,它可能會暴露在日誌文件中,pg_stat_activity

您幾乎總是想要存儲加密數據在bytea列。如果你確實堅持你可以用hex或base64對它進行編碼並將其推到text列中,但以後需要使用你的系統的開發人員和DBA會哭泣。

+0

謝謝你的深思熟慮的答案。我被你的論點說服了,日誌等意味着加密可能屬於應用程序。在我的情況下,這可能意味着將所有重要的文本列轉換爲字節類型並在應用程序上進行加密(但保留無信息的數字連接鍵和行ID不變)。如果一個人走上了你已經勾畫出來的路(通過應用程序而不是數據庫進行加密),是否有標準的方法來防止加密過程中的錯誤(例如無意中臨時使用錯誤的鍵)來加密數據? – Soferio

+0

@ user1642561可能有應用程序框架來幫助解決這個問題,但我不知道任何與您正在使用的工具相集成的東西。抱歉。可能值得發佈關於該問題的單獨問題。 –

+0

我可以問你澄清爲什麼使用bytea而不是字符串或文本列類型? – Soferio

相關問題