BCrypt เป็นอัลกอริทึมการแฮชที่ดีที่จะใช้ใน C # หรือไม่ หาได้จากไหนครับ? [ปิด]


129

ฉันได้อ่านว่าเมื่อแฮชรหัสผ่านโปรแกรมเมอร์หลายคนแนะนำให้ใช้อัลกอริทึม BCrypt

ฉันกำลังเขียนโปรแกรมในภาษา C # และสงสัยว่ามีใครรู้การใช้งาน BCrypt ที่ดีหรือไม่? ฉันพบหน้านี้แต่ฉันไม่รู้จริงๆว่ามันเป็นของปลอมหรือไม่

ฉันควรระวังอะไรบ้างเมื่อเลือกรูปแบบการแฮชรหัสผ่าน BCrypt เป็นการใช้งานที่ 'ดี' หรือไม่?

คำตอบ:


148

ประการแรกคำศัพท์บางคำที่มีความสำคัญ:

การแฮช - การกระทำของการรับสตริงและสร้างลำดับของอักขระที่ไม่สามารถเปลี่ยนกลับเป็นสตริงเดิมได้

Symmetric Encryption - (โดยปกติจะเรียกว่า 'การเข้ารหัส') - การกระทำของการรับสตริงและสร้างลำดับของอักขระที่สามารถ ถอดรหัสไปยังสตริงดั้งเดิมโดยใช้คีย์การเข้ารหัสเดียวกันกับที่เข้ารหัส

Rainbow Table -ตารางการค้นหาที่มีอักขระรูปแบบต่างๆที่แฮชในอัลกอริทึมการแฮชเฉพาะ

Salt - สตริงสุ่มที่รู้จักต่อท้ายสตริงดั้งเดิมก่อนที่จะแฮช

สำหรับ. NET Framework Bcrypt ยังไม่มีการนำไปใช้อ้างอิงที่ตรวจสอบแล้ว นี่เป็นสิ่งสำคัญเนื่องจากไม่มีทางทราบได้ว่ามีข้อบกพร่องร้ายแรงในการใช้งานที่มีอยู่หรือไม่ คุณจะได้รับการดำเนินการของbcrypt สำหรับ NET ที่นี่ ฉันไม่รู้เกี่ยวกับการเข้ารหัสมากพอที่จะบอกได้ว่าเป็นการใช้งานที่ดีหรือไม่ดี การเข้ารหัสเป็นฟิลด์ที่ลึกมาก อย่าพยายามที่จะสร้างวิธีการเข้ารหัสของคุณเอง อย่างจริงจัง.

หากคุณกำลังจะใช้การรักษาความปลอดภัยรหัสผ่านของคุณเอง (ถอนหายใจ) คุณต้องทำหลายอย่าง:

  1. ใช้วิธีกัญชาค่อนข้างเชื่อถือได้
  2. ใส่รหัสผ่านแต่ละรหัสก่อนแฮช
  3. ใช้เกลือที่ไม่ซ้ำกันและยาวสำหรับแต่ละรหัสผ่านและเก็บเกลือด้วยรหัสผ่าน
  4. ต้องการรหัสผ่านที่คาดเดายาก

น่าเสียดายที่แม้ว่าคุณจะทำทั้งหมดนี้ แต่แฮ็กเกอร์ที่มุ่งมั่นก็ยังสามารถหารหัสผ่านได้ แต่ก็ต้องใช้เวลานานมาก นั่นเป็นหัวหน้าศัตรูของคุณ: เวลา

อัลกอริทึม bcrypt ทำงานเพราะมันใช้เวลาห้าคำสั่งของขนาดอีกต่อไปเพื่อกัญชารหัสผ่านกว่า MD5 ; (และยังนานกว่า AES หรือ SHA-512) มันบังคับให้แฮ็กเกอร์ใช้เวลามากขึ้นในการสร้างตารางสายรุ้งเพื่อค้นหารหัสผ่านของคุณทำให้มีโอกาสน้อยที่รหัสผ่านของคุณจะตกอยู่ในอันตรายจากการถูกแฮ็ก

หากคุณกำลังใส่เกลือและแฮชรหัสผ่านและเกลือแต่ละชนิดแตกต่างกันแฮ็กเกอร์ที่มีศักยภาพจะต้องสร้างตารางสายรุ้งสำหรับเกลือแต่ละรูปแบบเพื่อให้มีตารางสายรุ้งสำหรับรหัสผ่านที่แฮช + เค็มหนึ่งอัน นั่นหมายความว่าหากคุณมีผู้ใช้ 1 ล้านคนแฮ็กเกอร์จะต้องสร้างตารางสายรุ้ง 1 ล้านตาราง หากคุณใช้เกลือเดียวกันสำหรับผู้ใช้ทุกคนแฮ็กเกอร์จะต้องสร้างตารางสายรุ้ง 1 โต๊ะเพื่อแฮ็คระบบของคุณได้สำเร็จ

หากคุณไม่ได้ใส่รหัสผ่านของคุณผู้โจมตีทั้งหมดต้องทำคือดึงตาราง Rainbow ที่มีอยู่สำหรับการใช้งานทุกครั้งที่นั่น (AES, SHA-512, MD5) และดูว่ามีอันใดตรงกับแฮชหรือไม่ นี้ได้ทำไปแล้วผู้โจมตีไม่จำเป็นต้องคำนวณเหล่านี้ตารางเรนโบว์ตัวเอง

ถึงแม้จะมีทั้งหมดนี้คุณได้มีการใช้การรักษาความปลอดภัยที่ดี หากพวกเขาสามารถใช้เวกเตอร์โจมตีอื่น (XSS, SQL Injection, CSRF และอื่น ๆ ) บนไซต์ของคุณได้สำเร็จการรักษาความปลอดภัยด้วยรหัสผ่านที่ดีก็ไม่สำคัญ ดูเหมือนจะเป็นคำสั่งที่ขัดแย้งกัน แต่ลองคิดดูสิ: ถ้าฉันสามารถรับข้อมูลผู้ใช้ทั้งหมดของคุณผ่านการโจมตีด้วยการฉีด SQL หรือฉันสามารถให้ผู้ใช้ของคุณให้คุกกี้ผ่าน XSS กับฉันได้ก็ไม่สำคัญว่ารหัสผ่านของคุณจะดีแค่ไหน ความปลอดภัยคือ .

แหล่งข้อมูลอื่น ๆ :

  1. Jeff Atwood: การเข้ารหัส. NET แบบง่าย (เหมาะสำหรับภาพรวมของการแฮช)
  2. Jeff Atwood: ฉันเพิ่งเข้าสู่ระบบในฐานะคุณ
  3. Jeff Atwood: คุณอาจจัดเก็บรหัสผ่านไม่ถูกต้อง
  4. Jeff Atwood: Speed ​​Hashing

หมายเหตุ:โปรดแนะนำแหล่งข้อมูลดีๆอื่น ๆ ฉันต้องอ่านบทความเป็นโหลโดยผู้เขียนหลายสิบคน แต่มีเพียงไม่กี่คนที่เขียนเรื่องนี้อย่างชัดเจนเหมือนที่เจฟฟ์ทำ โปรดแก้ไขในบทความเมื่อคุณพบ


อาจเพิ่มวรรคเกลือของคุณที่ต้องสุ่มเลือกเกลือ
Jacco

2
@Jacco กู๊ดโทรมาเสริม. แม้ว่านั่นจะไม่สำคัญ คุณสามารถใช้การประทับเวลาของการเข้าสู่ระบบสำหรับเกลือ ความแตกต่างที่เกิดขึ้นคือผู้โจมตีจำเป็นต้องคำนวณตารางรุ้งสำหรับเกลือแต่ละตัว นั่นคือสิ่งที่ทำให้ยากไม่ใช่ว่าสุ่มเลือก การสุ่มจะเพิ่มการสังเกตการณ์อีกชั้นหนึ่ง แต่ก็ไม่มีประโยชน์เมื่อผู้โจมตีสามารถมองเห็นฐานข้อมูลของคุณได้ (ซึ่งเป็นปัญหาที่ทำให้เราปวดใจตั้งแต่แรก)
George Stocker

3
ไม่จริงเกลือไม่จำเป็นต้องเป็นความลับสิ่งที่ไม่ซ้ำกันสำหรับแต่ละอินสแตนซ์ เนื่องจากเป็นไปไม่ได้ที่จะไม่ซ้ำกัน (เช่นเดียวกับทั่วโลก) การสุ่มจึงเป็นสิ่งที่ดีที่สุดถัดไป นอกจากนี้การประทับเวลาไม่ใช่เกลือที่ดีเนื่องจากมีเอนโทรปีไม่เพียงพอ
Jacco

7
ฉันมีปัญหากับคำสั่งของคุณ "หากพวกเขาสามารถใช้ XSS หรือ SQL injection ได้สำเร็จการรักษาความปลอดภัยด้วยรหัสผ่านที่ดีก็ไม่สำคัญ" ในทางตรงกันข้ามหากพวกเขาสามารถฉีด XSS หรือ SQL ไซต์ของคุณได้สำเร็จการรักษาความปลอดภัยด้วยรหัสผ่านที่ดีก็สำคัญยิ่งกว่า กุญแจสำคัญในที่นี้คือ "การป้องกันในเชิงลึก" - คุณควรเพิ่มความปลอดภัยให้มากที่สุดเท่าที่จะทำได้ในทุกชั้นของแอปพลิเคชันของคุณ
jammycakes

2
@jammycakes แน่นอน; ประเด็นของฉันหายไป: คุณไม่สามารถพูดว่า 'เฮ้เราแฮชและเกลือรหัสผ่านของเรา "เราโอเค"! "
George Stocker

74

คุณต้องไม่ใช้ BCrypt ใน. NET คุณต้องใช้ PBKDF2 เช่นเดียวกับการใช้งาน. NET framework ในตัว มันเป็นเพียงใช้ได้อย่างอิสระดำเนินการตรวจสอบแล้วเข้ารหัสใน .NET พร้อมกับการเป็นขั้นตอนวิธีการที่แนะนำโดย NIST

ก่อนหน้านี้ StackId ใช้ BCrypt และย้ายไป PBKDF2 ด้วยเหตุผลนี้:

สำหรับผู้ที่อยากรู้อยากเห็นเรากำลังแฮชรหัสผ่านกับ PBKDF2 รหัส Relavent อยู่ที่นี่ ( http://code.google.com/p/stackid/source/browse/OpenIdProvider/Current.cs#1135 ) ผ่านการกำหนดทิศทางสองสามชั้น ในการทำซ้ำก่อนหน้านี้เราใช้ BCrypt แต่ย้ายไปที่ PBKDF2 เนื่องจากสร้างไว้ในกรอบ. NET ในขณะที่ BCrypt ต้องการให้เราตรวจสอบการใช้งาน (ไม่มีการดำเนินการเล็กน้อย)

Kevin Montrose 27 พฤษภาคม 2554

(อัปเดตลิงค์บน GitHub)

แก้ไข:ดูเหมือนว่าความหมายของการยืนยันในรูปแบบการเข้ารหัสดูเหมือนจะไม่สามารถเข้าใจได้โดยง่ายการใช้งานที่ผ่านการตรวจสอบแล้วหมายความว่าได้รับการพิสูจน์แล้วว่าใช้งานได้โดยไม่มีข้อผิดพลาด ค่าใช้จ่ายนี้สามารถเข้าถึง 20,000 ดอลลาร์หรือสูงกว่าได้อย่างง่ายดาย ฉันจำสิ่งนี้ได้ตอนที่ฉันกำลังทำวิจัยเกี่ยวกับ OpenSSL และอ่านในที่ที่พวกเขาระบุว่าพวกเขายังไม่เสร็จสิ้นกระบวนการตรวจสอบทั้งหมด แต่ถ้าคุณต้องการการตรวจสอบอย่างละเอียดว่าพวกเขาสามารถชี้เส้นทางที่ถูกต้องให้คุณได้และกล่าวถึงค่าใช้จ่ายที่เกี่ยวข้อง ข้อกำหนดบางประการของรัฐบาลรวมถึงข้อกำหนดสำหรับอัลกอริทึมการเข้ารหัสที่ได้รับการยืนยัน

การใช้งาน bcrypt ใน. NET ยังไม่ได้รับการตรวจสอบ การใช้การใช้งานการเข้ารหัสที่ไม่ได้รับการยืนยันคุณไม่สามารถมั่นใจได้อย่างแน่นอนว่าไม่มีข้อผิดพลาดที่เป็นอันตรายโดยเจตนาเช่นการอนุญาตให้แบ็คดอร์เข้าไปในสิ่งที่เข้ารหัสหรือความผิดพลาดในการใช้งานโดยไม่ได้ตั้งใจซึ่งส่งผลให้ข้อมูลไม่ปลอดภัยในการเข้ารหัส

การแก้ไขปี 2014:สำหรับใครก็ตามที่ตั้งคำถามถึงความจำเป็นของการใช้อัลกอริธึมการเข้ารหัสที่ผ่านการตรวจสอบแล้วให้มองไปที่ความหายนะที่เกิดขึ้นจากการแฮ็กที่เจาะลึกซึ่งใช้ประโยชน์ใน OpenSSL นั่นคือค่าใช้จ่ายของการใช้งานที่ไม่ได้รับการยืนยัน ปลอดภัย .... จนกว่าคุณจะพบว่าบุคคลใดก็ตามสามารถอ่านเนื้อหาหน่วยความจำทั้งหมดของเซิร์ฟเวอร์ของคุณได้

ผู้เขียนการเปลี่ยนแปลงที่แนะนำ Heartbleed โรบิน Seggelmann ระบุว่าเขา "พลาดการตรวจสอบความถูกต้องของตัวแปรที่มีความยาว" และปฏิเสธความตั้งใจที่จะส่งการนำไปใช้งานที่มีข้อบกพร่อง หลังจากการเปิดเผยของ Heartbleed Seggelmann แนะนำให้มุ่งเน้นไปที่แง่มุมที่สองโดยระบุว่า OpenSSL ไม่ได้รับการตรวจสอบโดยผู้คนมากพอ

นี่คือคำจำกัดความของการใช้งานที่ไม่ได้รับการยืนยัน แม้แต่ข้อบกพร่องที่เล็กที่สุดก็อาจส่งผลให้ระบบรักษาความปลอดภัยทั้งหมดพิการได้

แก้ไขปี 2015:ลบภาษาตามคำแนะนำและแทนที่ด้วย Absolutes ข้อคิดเห็นของ Kevin Montrose ดั้งเดิมที่ฝังไว้สำหรับลูกหลาน


25
หากต้องการอ้างอิงความคิดเห็นที่เชื่อมโยง: "[เรา] ย้ายไปที่ PBKDF2 เนื่องจากสร้างไว้ในกรอบงาน. NET ในขณะที่ BCrypt ต้องการให้เราตรวจสอบการใช้งาน" โปรดทราบว่าความคิดเห็นไม่ได้บอกว่าอัลกอริทึมดีกว่าเพียงแค่ว่า SE Dev Team พิจารณาว่าการใช้งาน PBKDF2 ในตัวเชื่อถือได้มากกว่าไลบรารีภายนอก (ซึ่งในที่สุดก็คือการเรียกใช้การตัดสิน)
Piskvor ออกจากอาคาร

3
@Piskvor ฉันอัปเดตคำตอบของฉัน สิ่งนี้ไม่เกี่ยวกับสิ่งที่ทีม SO พิจารณาว่าปลอดภัย แต่เป็นการเรียกร้องการตัดสินระหว่างการพิสูจน์แล้วว่าปลอดภัยหรือหวังว่าจะปลอดภัย หลังเมื่อพูดถึงการเข้ารหัสเป็นสิ่งที่ยอมรับไม่ได้
Chris Marisic

6
ฉันสงสัยว่า SO จะย้ายรหัสผ่านที่แฮช bcrypt ทั้งหมดไปยังแฮชใหม่ได้อย่างไร พวกเขาไม่ต้องการรหัสผ่านดิบเพื่อแฮชโดยใช้อัลกอริทึมใหม่หรือไม่?
Dharmendar Kumar 'DK'

8
@DK ฉันไม่คิดว่าคุณต้องขอให้พวกเขารีเซ็ตรหัสผ่าน ในการเข้าสู่ระบบครั้งต่อไป (โดยที่พวกเขาระบุรหัสผ่านข้อความธรรมดา) คุณสามารถทำได้ฉันเชื่อ
Matt Kocaj

12
นี่เป็นคำแนะนำที่ไม่ดีและฉันรู้สึกประหลาดใจที่มีการโหวตเพิ่มขึ้นมากมาย การตรวจสอบการใช้งาน BCrypt ในภาษาที่มีการจัดการนั้นเป็นเรื่องเล็กน้อยมากกว่าการตรวจสอบบางอย่างเช่นการใช้ SSL ทั้งหมดใน C Heartbleed นั้นไม่เกี่ยวข้องโดยสิ้นเชิง คุณควรพูดถึงสิ่งที่ดีกว่าเช่น PHP ประเภทบีบบังคับปัญหาด้วยการตรวจสอบความเท่าเทียมกันของแฮช นอกจากนี้ในขณะที่เหมาะสมอย่างยิ่งในทางปฏิบัติ PBKDF2 คือ KDF ไม่ใช่อัลกอริทึมการแฮชรหัสผ่านในขณะที่ BCrypt เหมาะสมกว่า ไม่ว่าจะมีเหตุผลมากกว่าที่จะใช้ Argon2 ในทุกวันนี้ซึ่งมีไลบรารี C # ที่ผ่านการทดสอบอย่างดี
Polynomial
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.