การย้าย 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" ) ;
เนื่องจากการตั้งชื่อไลบรารีหากเนมสเปซอยู่หลังคำสั่ง use การโทรจึงเปลี่ยนไปเนื่องจาก .net ไม่สามารถแก้ไขการตั้งชื่อได้อย่างถูกต้อง ฉันขอแนะนำแทนที่จะป้อนเนมสเปซทั้งหมดที่คุณใช้เพียงนามแฝงการนำเข้าดังต่อไปนี้
using BC = BCrypt . Net . BCrypt ;
namespace DotNetSix ;
string passwordHash = BC . HashPassword ( "my password" ) ;
คุณยังสามารถสร้างนามแฝงได้ที่ระดับ CSProj และไม่จำเป็นต้องเพิ่มคำสั่งใช้เลย
ตัวอย่างนี้จะอนุญาตให้คุณใช้นามแฝง 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 Library นี้ และใช้โค้ดนี้
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 โมงจริงๆ และอาจลงทุนในแพ็คเกจเซิร์ฟเวอร์ที่ใหญ่กว่า
ขีดจำกัดรหัสผ่าน 56 ไบต์ที่แนะนำ (รวมถึงไบต์ที่สิ้นสุดด้วยค่า null) สำหรับ bcrypt เกี่ยวข้องกับขีดจำกัด 448 บิตของคีย์ปักเป้า ไบต์ใดๆ ที่เกินขีดจำกัดนั้นจะไม่ปะปนกันอย่างสมบูรณ์ในแฮช เช่นนี้ทำให้ขีดจำกัดสัมบูรณ์ 72 ไบต์ของรหัสผ่าน bcrypt มีความเกี่ยวข้องน้อยลง เมื่อพิจารณาถึงผลกระทบที่แท้จริงต่อการแฮชผลลัพธ์ของไบต์เหล่านั้น
ภาษาอื่นๆ ได้จัดการปัญหาการรับรู้นี้โดยการแฮชรหัสผ่าน/รหัสผ่านล่วงหน้าเพื่อเพิ่มเอนโทรปีที่ใช้ ดรอปบ็อกซ์เป็นหนึ่งในบทความสาธารณะเกี่ยวกับเรื่องนี้
คุณสามารถเลือกใช้การแฮชแบบปรับปรุงได้เพียงใช้โค้ดต่อไปนี้ (โดยพื้นฐานแล้วนำหน้าการเรียกเมธอดด้วย Enhanced)
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 hash ที่ใช้ SHA256 ซึ่งส่วนใหญ่เป็นความเข้ากันได้ DropBox ใช้ SHA512 ดังนั้นหากคุณทำงานที่ดรอปบ็อกซ์ คุณจะต้องการความเข้ากันได้ การเพิ่มประสิทธิภาพส่วนใหญ่เป็นส่วนขยายความสะดวกสบายที่คุณสามารถแฮชล่วงหน้าและส่งผ่านไปยังการเรียกเมธอดมาตรฐานได้แล้ว
มันทำอะไร? เราใช้ 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
Running TestGenerateSaltWithMaxWorkFactor
จะใช้เวลานานมาก
พอร์ต .Net ของ jBCrypt ถูกนำไปใช้ใน C# มันใช้ตัวแปรของตารางการคีย์ของอัลกอริธึมการเข้ารหัส Blowfish และแนะนำปัจจัยการทำงาน ซึ่งช่วยให้คุณกำหนดได้ว่าฟังก์ชันแฮชจะมีราคาแพงเพียงใด ทำให้อัลกอริธึมสามารถ "พิสูจน์ได้ในอนาคต"
นี่คือพอร์ตโดยตรงของ jBCrypt ที่เขียนโดย Damien Miller สำหรับเจตนาและวัตถุประสงค์ทั้งหมด ความแตกต่างที่สำคัญคือการเพิ่มวิธีการอำนวยความสะดวกบางอย่างและการแยกตัวประกอบใหม่เล็กน้อย วิธีที่ง่ายที่สุดในการตรวจสอบความเท่าเทียมกันของ BCrypt.Net กับ jBCrypt คือการเปรียบเทียบการทดสอบหน่วย
สำหรับภาพรวมว่าเหตุใด BCrypt จึงมีความสำคัญ โปรดดูวิธีจัดเก็บรหัสผ่านอย่างปลอดภัย โดยทั่วไปแล้ว นี่เป็นอัลกอริธึมการแฮชที่สามารถปรับเมื่อเวลาผ่านไปเพื่อให้ต้องใช้พลังงาน CPU มากขึ้นในการสร้างแฮช โดยพื้นฐานแล้วสิ่งนี้เป็นการป้องกันกฎของมัวร์บางประการ นั่นคือเมื่อคอมพิวเตอร์ทำงานเร็วขึ้น อัลกอริธึมนี้ก็สามารถปรับให้ต้องใช้พลังงาน CPU มากขึ้นได้ ยิ่งต้องใช้ CPU มากในการแฮรหัสผ่านที่กำหนด ยิ่งมีเวลามากขึ้นที่ "แฮ็กเกอร์" จะต้องลงทุนต่อรหัสผ่าน เนื่องจาก "ปัจจัยงาน" ถูกฝังอยู่ในแฮชผลลัพธ์ แฮชที่สร้างโดยอัลกอริธึมนี้จึงสามารถใช้งานร่วมกับไปข้างหน้า/ย้อนกลับได้
มันใช้ตัวแปรของตารางการคีย์ของอัลกอริธึมการเข้ารหัส Blowfish และแนะนำปัจจัยการทำงาน ซึ่งช่วยให้คุณกำหนดได้ว่าฟังก์ชันแฮชจะมีราคาแพงแค่ไหน ด้วยเหตุนี้ BCrypt จึงสามารถรักษากฎของมัวร์ได้ เมื่อคอมพิวเตอร์ทำงานเร็วขึ้น คุณสามารถเพิ่มปัจจัยการทำงานได้ และแฮชก็จะช้าลง
Niels Provos และ David Mazières ออกแบบโครงการ crypt() ที่เรียกว่า bcrypt ซึ่งมีพื้นฐานมาจาก Blowfish และนำเสนอที่ USENIX ในปี 1999[14]
รูปแบบการพิมพ์ของแฮชเหล่านี้เริ่มต้นด้วย
$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$.
สิ่งแรกและสำคัญที่สุดคือไลบรารีนี้มีต้นกำเนิดมาจากพอร์ตของ jBCrypt จาก mindrot
และต่อมามีการตั้งค่าการแก้ไข 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
เพื่อใช้ปล่อย
เวอร์ชัน 4.0.0 (การเปลี่ยนแปลงล่าสุด) - พบข้อบกพร่องใน Enhanced Hashing
ที่ทำให้แฮชที่สร้างขึ้นไม่สามารถใช้งานได้ระหว่างภาษาต่างๆ V4 มีการแก้ไขสำหรับสิ่งนี้ เช่นเดียวกับการเพิ่มเวกเตอร์ทดสอบจาก PHP และ Python เพื่อให้แน่ใจว่าปัญหาจะยังคงได้รับการแก้ไขในอนาคต V4 ยังลบตัวเลือก 384 แบบเดิมที่มาก่อนที่จะเพิ่ม Base64
v3.5.0 - พบข้อบกพร่องใน Enhanced Hashing
ที่ทำให้แฮชที่สร้างขึ้นไม่สามารถใช้งานได้ระหว่างภาษาต่างๆ เนื่องจากเป็นส่วนหนึ่งของเวอร์ชันแก้ไข 3.5 มีความสามารถใน Verify
และ HashPassword
ได้รับพารามิเตอร์ v4CompatibleEnhancedEntropy
เพิ่มเติม สิ่งนี้ทำให้ผู้ใช้สามารถตรวจสอบแฮชที่ปรับปรุงแล้วได้ตามปกติ จากนั้นแฮชอีกครั้ง + จัดเก็บโดยใช้ V4 ฟังก์ชันนี้มีไว้เพื่ออนุญาตการโยกย้ายเท่านั้น และจะถูกลบออกในเวอร์ชัน 4
v3.3.3 - ประสิทธิภาพ (การลดฮีป) สำหรับ netcore และการลบ regex https://github.com/BcryptNet/bcrypt.net/releases/tag/3.3.0
เวอร์ชัน 2.1.3 -
เวอร์ชัน 2.1.2 -
PasswordNeedsReshash
เป็น PasswordNeedsRehash
เวอร์ชัน 2.1.1 -
เวอร์ชัน 2.1.0 -
PasswordNeedsReshash(string hash, int newMinimumWorkLoad)
เป็นวิธีตัวช่วยสำหรับนักพัฒนาที่จะใช้เมื่อเข้าสู่ระบบผู้ใช้เพื่อเพิ่มปริมาณงานแบบเดิมValidateAndReplacePassword
เพื่ออนุญาตการตรวจสอบและการแทนที่รหัสผ่านแบบอินไลน์ พ่น BcryptAuthenticationException
ในกรณีที่การรับรองความถูกต้องล้มเหลวเวอร์ชัน 2.0.1 -
เวอร์ชัน 2.0.0 -
แพ็คเกจใหม่ล่าสุดสำหรับ .net ส่วนใหญ่และมี safe-equals เพื่อลดความเสี่ยงจากการโจมตีด้านเวลา https://en.wikipedia.org/wiki/Timing_attack / https://cryptocoding.net/index.php/Coding_rules#Compare_secret_strings_in_constant_time ในทางเทคนิคแล้ว รายละเอียดการใช้งาน BCrypt ในทางทฤษฎีสามารถบรรเทาการโจมตีตามเวลาได้ แต่ฟังก์ชันการตรวจสอบอย่างเป็นทางการของ Bcrypt.net มีความเสี่ยงที่จะถูกโจมตีตามเวลา เนื่องจากมันส่งคืนทันทีที่พบไบต์ที่ไม่ตรงกันในการเปรียบเทียบแฮช