2016-06-10 130 views
0

我在我的.NET(C#)客戶端中使用CryptSharp Library,用隨機生成的鹽(Blowfish)對用戶密碼進行哈希處理。在C#中隨機鹽散列?

然後我將散列密碼發送到我的遠程服務器,它存儲在MySQL數據庫中。

當我嘗試使用相同的明文密碼登錄時,發送內容和數據庫中存儲的內容之間存在散列不匹配。 (最有可能是由於鹽每次都在變化)

我不想發送一個未加密的明文密碼到我的PHP端,我怎樣才能實現這一點,而不使用靜態鹽?

散列(C#):

string passHash = Crypter.Blowfish.Crypt(Password.Text, Crypter.Blowfish.GenerateSalt()); 

我不希望要創建一個新的列來存儲客戶的鹽在註冊,但如果我必須我會的。

+0

你爲什麼要使用河豚?還有其他更直接的方法可以直接從.NET框架生成哈希值。那麼,你有什麼特別的原因讓你使用Blowfish? –

+0

如果不是Bcrypt(Blowfish),你會推薦什麼? – user1954141

+0

使用SHA1從.NET框架管理,請參閱下面的答案 –

回答

0

答案很簡單,不相關的正在使用的語言:

  1. 如果您希望服務器散列密碼存儲在數據庫中,你可以將其與任何散列函數存儲(I」 d建議使用SHA256或BCrypt,如果你想使暴力破解花費更長時間,那麼BCrypt的好處是鹽和迭代次數直接存儲在散列中,因此數據庫中不需要額外的列)。

  2. 如果你想對它們進行鹽化,你需要存儲一個salt列並將其傳遞給客戶端以在散列期間使用。通常你會爲每個用戶使用一個隨機salt,並且它只會在密碼更改時更改。這是建議但不是必需的 - 它使彩虹桌攻擊毫無用處。

  3. 如果您擔心通過網線傳輸,而不是特別關注數據庫,您可以在認證過程中在服務器上生成一個隨機鹽,並且只使用一次 - 但服務器將需要原始密碼進行比較。

你也可以結合所有這些方法,雖然我不認爲這是任何地方的標準做法。

0

您可以使用此:

var result = string.Empty; 
using (var sha1 = new SHA1Managed()) 
{ 
    result = ToHex(sha1.ComputeHash(Encoding.ASCII.GetBytes(Password.Text))); 
} 

ToHex看起來是這樣的:

public static string ToHex(byte[] bytes) 
{ 
    return string.Concat(bytes.Select(b => b.ToString("X2"))); 
} 

上面的代碼不會產生相同的哈希值時,參與而不需要鹽多次調用。

在.NET框架中還支持其他更安全的SHA算法版本,如SHA256Managed。使用SHA1或SHA256取決於您的安全要求。

+0

這是一種非常不安全的存儲密碼的方式,也不是哈希醃製的,也沒有迭代來控制散列所需的時間。這樣的哈希值可能太蠻力(大約5千兆/秒)。 – martinstoeckli

0

加密密碼的目的是將密碼安全地存儲在數據庫中。 CryptSharp無法幫助您確保通過線路傳輸。

您可以採取多種方法,但最簡單的方法可能是通過SSL與服務器通信。如果您不想使用公共CA,請使用自簽名證書並掛接ServicePointManager.ServerCertificateValidationCallback以接受您自己的CA或證書。

0

要將密碼從客戶端傳輸到服務器,需要加密的HTTPS/SSL連接。它會在將用戶輸入發送到客戶端之前加密用戶輸入,因此ManInTheMiddle無法竊聽。散列必須在服務器端完成,至少是散列的一部分。

CryptSharp支持通用存儲格式,並且在結果散列中包含salt。不幸的是,似乎沒有一種驗證方法,它將提取使用的鹽,至少我找不到一種。

我可以推薦另一個庫BCrypt.Net,那裏的鹽也用哈希(無需額外的字段)一起存儲和驗證是非常簡單的:BCrypt.Verify(password, stored_hash)