2014-04-30 83 views
2

我通常對存儲敏感信息非常謹慎,並且希望儘可能使用Facebook/Twitter登錄,以便他們可以處理密碼。不過,我已經到了一個項目,除了在數據庫中存儲用戶名/密碼之外別無選擇,我希望確保我使用的代碼在安全性方面完美無瑕。SQL Server - 存儲密碼

我已經編寫了下面的程序,它將生成哈希密碼並計劃將@strPassword和@strSalt的結果存儲在我的用戶表中。

網站/移動應用程序將哈希密碼並通過HTTPS連接發佈到Web服務,該服務將哈希結果與鹽結合起來,並再次哈希它,以便將其與表中存儲的密碼進行比較。

從我讀過的東西應該可以防止彩虹表被用來解密它,以及使用SHA512這應該防止暴力,最後通過HTTPS,這將防止任何東西在傳輸中竊取密碼。如果病毒在客戶端設備上可以保存密碼的副本,則它已經被部分散列。

這裏是否存在潛在的缺陷或者是否有更好的方法來實現?

DECLARE @strPassword VARCHAR(128) 
DECLARE @strSalt VARCHAR(36) 
DECLARE @strHashMethod VARCHAR(10) = 'SHA2_512' 

SET @strPassword = HASHBYTES(@strHashMethod, 'MyPassword') 
SET @strSalt = CONVERT(VARCHAR(36), NEWID()) 
SET @strPassword = HASHBYTES(@strHashMethod, @strSalt + @strPassword) 

SELECT CONVERT(VARBINARY(128), @strPassword) 
+0

是@str密碼用戶的純文本密碼? – paqogomez

+0

我的歉意。這段代碼是用戶在內部系統(WinForms)上創建帳戶時運行的腳本。密碼以純文本形式傳遞到SQL,然後使用SHA_512進行哈希處理,再與鹽結合,然後再次散列。沒有純文本密碼存儲在任何地方。 –

+0

我明白了,我的觀點只是爲了確保您沒有存儲用戶的純文本密碼。這會導致像最近Target經歷的黑客攻擊。 – paqogomez

回答

0

看起來很安全!

您可以在一個迭代次數拋出,如果你喜歡它的感覺,例如,循環這100次只是你的最後一行之前:

SET @strPassword = HASHBYTES(@strHashMethod, @strPassword) 

或者,IC(迭代計數)可能是之間的隨機INT ,比如說100和1000,並且存儲在底層表中的哈希密碼和salt旁邊。

使用NEWID()創建鹽有點奇怪。我可能只是使用CRYPT_GEN_RANDOM(16)。

+0

嗨,感謝您的評論!我會考慮迭代來多次散列它。我在CRTYPT_GEN_RANDOM上使用NEWID的原因是我需要支持SQL 2005到2012年。除非SQL 2005有更好的方法嗎? –

+0

在我的回答中意識到輕微的失望:鹽只會在第一次出現,並且不會在每次迭代時重新應用。 我認爲如果你支持SQL-2005,NEWID()會有很大的意義。優雅。 –