2009-02-18 70 views
17

我們將所有應用程序和數據庫密碼以純文本形式存儲在源代碼管理中。我們這樣做是因爲我們的構建/部署過程會生成所需的配置文件,並且也會進行需要這些密碼的實際部署(即:針對數據庫運行sql需要使用有效憑據登錄到數據庫)。有沒有人有類似的需求,你可以實現這種類型的功能,而不是以純文本存儲密碼?源代碼管理中的密碼存儲

+1

將密碼置於o/s用戶環境變量中。 – 2013-11-03 00:06:38

回答

21

如果您的計劃是存儲所有代碼和配置信息以直接從版本控制運行生產系統,並且無需人工干預,那麼您就被搞砸了。爲什麼?這完全違反了舊的安全公理「永遠不要寫下你的密碼」。讓我們通過否定做一個證明。

首先,您在配置文件中使用純文本密碼。這是不好的,任何人都可以看到這些文件。

第二次,我們會加密密碼!但是現在代碼需要知道如何解密密碼,所以您需要將解密密鑰置於代碼中的某處。這個問題剛剛被推到一個水平。

如何使用公鑰/私鑰?與密碼相同的問題,密鑰必須位於代碼中。

未存儲在版本控制中的本地配置文件的使用仍會將密碼以及在磁盤上進行加密並讀取它們的方式提供給攻擊者。通過確保配置文件的權限非常有限,您可以稍微加強一點,但是如果該框根深蒂固,那麼您就被搞砸了。

這引出我們爲什麼把密碼放在磁盤上是一個壞主意。它違反了安全防火牆的概念。一臺包含登錄信息的受損機器意味着其他機器將受到危害。一臺維護不善的機器可能會推倒整個組織。

在某個時候,人類將不得不注入重要的祕密來啓動信任鏈。你可以做的是加密代碼中的所有祕密,然後當系統啓動時,人工手動輸入密鑰來解密所有密碼。這就像Firefox使用的主密碼系統。這是開放的濫用,因爲一旦一個密碼被泄露,許多系統可能會受到危害,但它很方便,可能更安全,因爲用戶只需記住一個密碼並且不太可能將其寫下。

最後一點是確保登錄信息應該被破壞(並且您應該始終假設它會)A)攻擊者無法用它做很多事情B)您可以快速關閉受感染的賬戶。前者意味着只爲帳戶提供儘可能多的訪問權限。例如,如果您的程序只需要從數據庫中讀取,那麼它只能登錄限於SELECT的帳戶。通常,刪除所有訪問權限,然後僅在必要時添加它。小心刪除權利,以免你從little Bobby Tables訪問。

後者意味着您爲每個用戶/組織/項目提供自己的登錄,即使他們可以擁有完全相同的權限和特權並訪問相同的數據。這有點麻煩,但這意味着如果一個系統被破壞,您可以在不關閉整個業務的情況下快速關閉該賬戶。

-8

如果在C中進行操作,您可以將其存儲爲一個字符數組,並將字符作爲十進制引用。不知道這是否會破壞字符串,但可能有助於緩解某些問題。

char pass[]={72, 101, 108, 108, 111}; 
+1

Boshfpngvba qbrf abg cebivqr frphevgl! – Schwern 2009-02-18 03:15:32

+0

eewwwwwwwwwwwww – 2010-02-27 20:59:18

-5

以加密形式存儲密碼。編寫一個自定義例程,解密密碼並在構建時更新配置文件。這可以很容易地與像Ant這樣的構建工具集成。

+3

那麼你把解密密鑰放在哪裏? – Schwern 2009-02-18 03:38:53

-1

你沒有提到的語言,所以這裏我們使用vb.net解決方案:

Imports System.Web.Security 
Imports System.Security.Cryptography 
Imports System.Text 
Imports Microsoft.Win32 

Public Class myCrypt 

Private myKey As String = "somekeyhere" 
Private cryptDES3 As New TripleDESCryptoServiceProvider() 
Private cryptMD5Hash As New MD5CryptoServiceProvider() 


Private Function Decrypt(ByVal myString As String) As String 
    cryptDES3.Key = cryptMD5Hash.ComputeHash(ASCIIEncoding.ASCII.GetBytes(myKey)) 
    cryptDES3.Mode = CipherMode.ECB 
    Dim desdencrypt As ICryptoTransform = cryptDES3.CreateDecryptor() 
    Dim buff() As Byte = Convert.FromBase64String(myString) 
    Decrypt = ASCIIEncoding.ASCII.GetString(desdencrypt.TransformFinalBlock(buff, 0, buff.Length)) 
End Function 

Private Function Encrypt(ByVal myString As String) As String 
    cryptDES3.Key = cryptMD5Hash.ComputeHash(ASCIIEncoding.ASCII.GetBytes(myKey)) 
    cryptDES3.Mode = CipherMode.ECB 
    Dim desdencrypt As ICryptoTransform = cryptDES3.CreateEncryptor() 
    Dim MyASCIIEncoding = New ASCIIEncoding() 
    Dim buff() As Byte = ASCIIEncoding.ASCII.GetBytes(myString) 
    Encrypt = Convert.ToBase64String(desdencrypt.TransformFinalBlock(buff, 0, buff.Length)) 
End Function 

End Class 
+0

我們的構建/部署過程是ANT。我們的應用程序代碼恰好是Java。 – 2009-02-18 02:36:52

+3

MD5? TripleDes的?該死的,MD5已經妥協了,3DES正在出路。使用AES和SHA256。更重要的是,一旦你加密了登錄憑證,你在哪裏放置解密密鑰?雞蛋。 – Schwern 2009-02-18 03:48:20

6

我假設的目標是,你不希望你的公司的私人密碼可用,加密,解密或以其他方式發送給任何其他人應該允許訪問源的其餘部分。

下面是我如何做到這一點。我從TikiWiki中複製了這種模式,也是這樣做的。

在一些通常包含密碼的文件中,將它們設置爲虛擬值,無所謂。將其設置爲任何您的客戶應該看到的。對開發人員附近發表評論,讓其單獨保留此文件並更改第二個文件。

在第二個文件中,如果它不存在,則會創建實際的密碼。安排這個文件被包含,導入,無論如何,由第一個文件。

安排源代碼管理忽略該文件。可能看起來像這樣:

# in .gitignore 
localsettings.py 

# in settings.py 
## Alter this value to log into the snack machine: 
## developers: DON'T alter this, instead alter 'localsettings.py' 
SECRET_VALUE = "" 
try: 
    from localsettings import * 
except: 
    pass 

# in localsettings.py 
SECRET_VALUE = "vi>emacs" 
1

我已經建立了數據庫用戶ID /密碼對不是代碼放下的一部分的系統。關鍵是要設置一個特定於站點的配置機制。然後你可以把這些信息放在有問題的盒子裏,而不用作爲代碼庫的一部分。

還有一個好處:你不僅可以針對不同的代碼丟棄,而且針對不同的開發者有不同的密碼。 :-)