移植 bcrypt.codeplex.com,具有增強的安全性、缺少的修復、功能和更好的 .net 支援。
使用 nuget 或 Paket 下載(https://fsprojects.github.io/Paket/)
套件:https://www.nuget.org/packages/BCrypt.Net-Next/
簽名包 - https://www.nuget.org/packages/BCrypt.Net-Next.StrongName/
我們的測試工具資料夾和單元測試中有各種範例
最簡單的用法如下...
對密碼進行哈希處理:
顯示檔案範圍的命名空間;如果需要的話,想像一下大括號。
Top level namespace
namespace DotNetSix ;
using BCrypt . Net ;
string passwordHash = BCrypt . HashPassword ( "my password" ) ;
由於庫的命名,如果命名空間位於 using 語句之後,則呼叫會更改,因為 .net 無法正確解析命名,我建議您不要輸入整個命名空間,只需使用匯入別名,如下所示。
using BC = BCrypt . Net . BCrypt ;
namespace DotNetSix ;
string passwordHash = BC . HashPassword ( "my password" ) ;
您也可以在 CSProj 層級執行別名操作;而且根本不需要加入 using 語句
此範例可讓您在程式碼中使用別名 BC.HashPassword()
< ItemGroup >
<!-- emits global using BcryptNet = global::BCrypt.Net.BCrypt; -->
< Using Include = " BCrypt.Net.BCrypt " Alias = " BC " />
</ ItemGroup >
此版本允許您僅在程式碼庫中呼叫Verify
和HashPassword
而無需任何其他參考。
< ItemGroup >
<!-- emits global using static global::BCrypt.Net.BCrypt; -->
< Using Include = " BCrypt.Net.BCrypt " Static = " True " />
</ ItemGroup >
注意:雖然該庫允許您提供自己的鹽,但強烈建議您允許該庫為您生成鹽。提供這些方法是為了保持相容性以及可能需要使用它們的更高級的跨平台要求。
若要根據雜湊值驗證密碼(假設您已儲存雜湊值並從儲存體中檢索以進行驗證):
之前所有有關命名空間的註釋也適用於此處
BCrypt . Verify ( "my password" , passwordHash ) ;
此雜湊實作將自動為您產生鹽,並將工作因子(2^輪數)設為 11(與大多數實作中的預設值相匹配,目前被視為良好的安全/風險等級)。
為了節省數學計算,下面提供了一個涵蓋迭代的小表。為了相容性,該庫中允許的最小值為 4,最大值為 31(在 31 時,您的處理器將希望死亡)。
| Cost | Iterations |
|-------|--------------------------|
| 8 | 256 iterations |
| 9 | 512 iterations |
| 10 | 1,024 iterations |
| 11 | 2,048 iterations |
| 12 | 4,096 iterations |
| 13 | 8,192 iterations |
| 14 | 16,384 iterations |
| 15 | 32,768 iterations |
| 16 | 65,536 iterations |
| 17 | 131,072 iterations |
| 18 | 262,144 iterations |
| 19 | 524,288 iterations |
| 20 | 1,048,576 iterations |
| 21 | 2,097,152 iterations |
| 22 | 4,194,304 iterations |
| 23 | 8,388,608 iterations |
| 24 | 16,777,216 iterations |
| 25 | 33,554,432 iterations |
| 26 | 67,108,864 iterations |
| 27 | 134,217,728 iterations |
| 28 | 268,435,456 iterations |
| 29 | 536,870,912 iterations |
| 30 | 1,073,741,824 iterations |
| 31 | 2,147,483,648 iterations |
etc
您可以透過建立控制台程式、新增此 BCrypt 庫並使用此程式碼來執行簡單的基準測試。
var cost = 16 ;
var timeTarget = 100 ; // Milliseconds
long timeTaken ;
do
{
var sw = Stopwatch . StartNew ( ) ;
BCrypt . HashPassword ( "RwiKnN>9xg3*C)1AZl.)y8f_:GCz,vt3T]PI" , workFactor : cost ) ;
sw . Stop ( ) ;
timeTaken = sw . ElapsedMilliseconds ;
cost -= 1 ;
} while ( ( timeTaken ) >= timeTarget ) ;
Console . WriteLine ( "Appropriate Cost Found: " + ( cost + 1 ) ) ;
Console . ReadLine ( ) ;
這將從 16 開始,即65,536 iterations
,並降低成本,直到達到時間目標。這取決於您認為允許的時間,但如果它低於 10,我強烈建議將其保留在 10,並可能投資更大的伺服器包。
bcrypt 建議的 56 位元組密碼限制(包括空終止位元組)與 Blowfish 金鑰的 448 位元限制相關;超出該限制的任何位元組都不會完全混合到雜湊中,因此考慮到這些位元組對生成的雜湊的實際影響,bcrypt 密碼的 72 個位元組絕對限制不太相關。
其他語言則透過預先散列密碼短語/密碼以增加使用的熵來處理這個感知問題,dropbox 是這方面較為公開的文章之一。
您只需使用以下程式碼即可選擇增強雜湊(基本上在方法呼叫前加上“增強”前綴)
var enhancedHashPassword = BCrypt . EnhancedHashPassword ( myPassword ) ;
var validatePassword = BCrypt . EnhancedVerify ( myPassword , enhancedHashPassword ) ;
預設情況下,該函式庫使用密碼的 SHA384 哈希,然後將產生的材料傳遞給 bcrypt,透過通常的 bcrypt 例程形成哈希。如果您想要指定不同版本的 SHA,或者只是希望在程式碼中明確設定所使用的版本,以防它在庫的主要版本中發生更改,您可以透過對上述內容進行以下更改來實現。
var enhancedHashPassword = BCrypt . EnhancedHashPassword ( myPassword , hashType : HashType . SHA384 ) ;
var validatePassword = BCrypt . EnhancedVerify ( myPassword , enhancedHashPassword , hashType : HashType . SHA384 ) ;
為什麼選擇 SHA384?它在性能、安全性、碰撞保護之間取得了良好的平衡,並且是唯一不易受到長度擴展攻擊的版本https://blog.skullsecurity.org/2012/everything-you-need-to-know-about -hash -長度擴展攻擊。
我應該使用增強熵嗎?使用它你不會有任何損失
為什麼需要更改 SHA 類型?有些函式庫(例如 PassLib 哈希)使用 SHA256,所以主要是相容性問題。 DropBox 使用 SHA512,因此如果您在 Dropbox 工作,您會需要相容性。增強主要是一種方便的擴展,因為您已經可以預先哈希並傳遞到標準方法呼叫中。
它有什麼作用?我們將密碼的 utf8 位元組作為 inputBytes SHA 對它們進行雜湊處理,轉換為 base64(為了與其他語言實作相容),然後使用這些位元組執行標準 bcrypt 呼叫。
您至少需要 VS2022 以及目前的 SDK https://www.microsoft.com/net/download;
nuget 包可以透過執行buildfornuget.cmd
或
dotnet restore . s rc
dotnet pack . s rc B Crypt.Net --configuration Release
您可以鍵入dotnet test .srcBCrypt.Net.UnitTests
TestGenerateSaltWithMaxWorkFactor
用 C# 實作的 jBCrypt 的 .Net 連接埠。它使用 Blowfish 加密演算法的金鑰計劃的變體,並引入工作因子,使您可以確定雜湊函數的成本,從而使演算法「面向未來」。
出於所有意圖和目的,這是由 Damien Miller 編寫的 jBCrypt 的直接移植。主要區別是添加了一些便捷方法和一些溫和的重構。驗證 BCrypt.Net 與 jBCrypt 同等性的最簡單方法是比較單元測試。
有關 BCrypt 為何如此重要的概述,請參閱如何安全地儲存密碼。一般來說,它是一種哈希演算法,可以隨著時間的推移進行調整,以需要更多的 CPU 能力來產生哈希值。從本質上講,這提供了一些針對摩爾定律的保護。也就是說,隨著電腦變得更快,可以調整演算法以需要更多的 CPU 能力。哈希給定密碼所需的 CPU 能力越多,「駭客」必須為每個密碼投入的時間就越多。由於“工作因子”嵌入到結果雜湊中,因此該演算法產生的雜湊是前向/後向相容的。
它使用 Blowfish 加密演算法的金鑰調度的變體並引入工作因子,使您可以確定雜湊函數的成本。正因為如此,BCrypt才能跟上摩爾定律。隨著計算機變得越來越快,您可以增加工作因素,並且雜湊會變得更慢。
Niels Provos 和 David Mazières 基於 Blowfish 設計了一個名為 bcrypt 的 crypt() 方案,並於 1999 年在 USENIX 上提出。
這些哈希值的可列印形式以
$2$ – Currently obsolete
$2a$ – The current key used to identify this scheme.
Since a major security flaw was discovered in 2011 in a third-party implementation of the algorithm,
hashes indicated by this string are now ambiguous and might have been generated by the flawed
implementation, or a subsequent fixed, implementation.
The flaw may be triggered by some password strings containing non-ASCII characters, such as specially
crafted password strings.
$2b$ – Used by some recent implementations which include a mitigation to a wraparound problem.
Previous versions of the algorithm have a problem with long passwords. By design, long passwords
are truncated at 72 characters, but there is an 8-bit wraparound problem with certain password
lengths resulting in weak hashes.
$2x$ – Post-2011 bug discovery, old hashes can be renamed to be $2x$ to indicate that they were generated with
the broken algorithm. These hashes are still weak, but at least it's clear which algorithm was used to
generate them.
$2y$ – Post Post-2011 bug discovery, $2y$ may be used to unambiguously use the new, corrected algorithm. On an
implementation suffering from the bug, $2y$ simply won't work. On a newer, fixed implementation, it will
produce the same result as using $2a$.
首先也是最重要的是,這個函式庫起源於mindrot
的 jBCrypt 端口,隨後 bcrypt 版本被設定為匹配,在本例中為$2a$
。這已被更改,因為僅處理單一修訂版會導致跨平台問題,而實作則更改了其修訂版以處理遷移和其他問題。
The original bcrypt code (released in OpenBSD 2.1) identified itself as
$2$. Shortly after release, a bug was fixed and the hash identifier
changed to $2a$. Support for "minor" versions wasn't really
planned, but it was backwards compatible.
Solar Designer wrote a second implementation of bcrypt. This
reimplementation suffered from a flaw dealing with 8 bit characters
and led to the introduction of the 'x' and 'y' flavours. OpenBSD did
not have this problem and supports neither 'x' nor 'y' hash versions.
---
Solar found a bug in their OpenBSD implementation of bcrypt when hashing
long passwords. The length is stored in an unsigned char type, which
will overflow and wrap at 256. Although we consider the existence of
affected hashes very rare, in order to differentiate hashes generated
before and after the fix, we are introducing a new minor 'b'.
OpenBSD 5.5 (coming this spring) will accept and verify 'b' hashes,
although it will still generate 'a' hashes. OpenBSD 5.6 (coming this
fall) will change to generating 'b' hashes by default.
A future release of Solar's bcrypt code should also support 'b'.
2a、2x、2y 和 2b 之間沒有區別。它們都輸出相同的結果。
發行說明位於 https://github.com/BcryptNet/bcrypt.net/releases
v4.0.3 - 新增了 .net 6 目標;整理目標。
v4.0.2 - 新增了 .net 5 目標;將shaxxx
創建包裝在 using 中發布。
v4.0.0(重大變更) - 發現Enhanced Hashing
雜湊中的一個錯誤,導致建立的雜湊在不同語言之間無法操作。 V4 提供了此問題的修復,並添加了來自 PHP 和 Python 的測試向量,以確保該問題在未來得到解決。 V4 也刪除了新增 Base64 之前的舊 384 選項。
v3.5.0 - 發現Enhanced Hashing
中的一個錯誤,導致創建的雜湊在不同語言之間無法操作。作為修復的一部分,3.5 版本包含了Verify
功能,並為HashPassword
提供了額外的v4CompatibleEnhancedEntropy
參數。這允許用戶正常驗證其增強型雜湊;然後使用V4重新散列+儲存。此功能純粹是為了允許遷移,在 V4 中被刪除。
v3.3.3 -netcore 的效能(堆疊減少)和刪除正規表示式 https://github.com/BcryptNet/bcrypt.net/releases/tag/3.3.0
v2.1.3 -
v2.1.2 -
PasswordNeedsReshash
中的拼字錯誤修正為PasswordNeedsRehash
v2.1.1 -
v2.1.0 -
PasswordNeedsReshash(string hash, int newMinimumWorkLoad)
作為開發人員在使用者登入時使用的輔助方法,以增加舊工作負載ValidateAndReplacePassword
方法以允許內聯密碼驗證和替換。如果身份驗證失敗,則拋出BcryptAuthenticationException
。v2.0.1 -
v2.0.0 -
為大多數 .net 打包的新版本並包含安全性等於,以降低計時攻擊的風險 https://en.wikipedia.org/wiki/Timing_attack / https://cryptocoding.net/index.php/Coding_rules#Compare_secret_strings_in_constant_time從技術上講,BCrypt 的實作細節理論上可以減輕定時攻擊。但Bcrypt.net官方驗證函數很容易受到定時攻擊,因為一旦在雜湊比較中發現不匹配的字節,它就會回傳。