วิธีแฮชรหัสผ่านแบบยาว (> 72 ตัวอักษร) ด้วยปักเป้า


91

สัปดาห์ที่แล้วฉันอ่านบทความมากมายเกี่ยวกับการแฮชรหัสผ่านและปักเป้าดูเหมือนว่า (หนึ่งใน) อัลกอริทึมการแฮชที่ดีที่สุดในตอนนี้ - แต่นั่นไม่ใช่หัวข้อของคำถามนี้!

ขีด จำกัด 72 อักขระ

ปักเป้าพิจารณาเฉพาะอักขระ 72 ตัวแรกในรหัสผ่านที่ป้อน:

<?php
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$hash = password_hash($password, PASSWORD_BCRYPT);
var_dump($password);

$input = substr($password, 0, 72);
var_dump($input);

var_dump(password_verify($input, $hash));
?>

ผลลัพธ์คือ:

string(119) "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)"
string(72) "Wow. This is a super secret and super, super long password. Let's add so"
bool(true)

อย่างที่คุณเห็นเฉพาะ 72 ตัวแรกเท่านั้นที่มีความสำคัญ Twitter ใช้ปักเป้าหรือ bcrypt เพื่อจัดเก็บรหัสผ่าน ( https://shouldichangemypassword.com/twitter-hacked.php ) และคาดเดาสิ่งที่: เปลี่ยนรหัสผ่าน twitter ของคุณเป็นรหัสผ่านยาวที่มีอักขระมากกว่า 72 ตัวและคุณสามารถเข้าสู่บัญชีของคุณได้โดย ป้อนอักขระ 72 ตัวแรกเท่านั้น

ปักเป้าและพริกไทย

มีความคิดเห็นที่แตกต่างกันมากมายเกี่ยวกับรหัสผ่าน "peppering" บางคนบอกว่าไม่จำเป็นเพราะคุณต้องสมมติว่าสายพันธุ์พริกไทยลับนั้นเป็นที่รู้จัก / เผยแพร่ดังนั้นจึงไม่ช่วยเพิ่มแฮช ฉันมีเซิร์ฟเวอร์ฐานข้อมูลแยกต่างหากดังนั้นจึงค่อนข้างเป็นไปได้ว่ามีเพียงฐานข้อมูลเท่านั้นที่รั่วไหลไม่ใช่พริกไทยคงที่

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

ดังนั้นฉันคิดว่าอย่างน้อยการกำหนดรหัสผ่านก็ไม่ใช่ทางเลือกที่ดี

ข้อเสนอแนะ

คำแนะนำของฉันในการรับแฮชปักเป้าสำหรับรหัสผ่านที่มีอักขระมากกว่า 72 ตัว (และพริกไทย) คือ:

<?php
$pepper = "foIwUVmkKGrGucNJMOkxkvcQ79iPNzP5OKlbIdGPCMTjJcDYnR";

// Generate Hash
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$password_peppered = hash_hmac('sha256', $password, $pepper);
$hash = password_hash($password_peppered, PASSWORD_BCRYPT);

// Check
$input = substr($password, 0, 72);
$input_peppered = hash_hmac('sha256', $input, $pepper);

var_dump(password_verify($input_peppered, $hash));
?>

นี้จะขึ้นอยู่กับคำถามนี้ : การกลับมา password_verifyfalse

คำถาม

วิธีที่ปลอดภัยกว่าคืออะไร? รับแฮช SHA-256 ก่อน (ซึ่งส่งคืนอักขระ 64 ตัว) หรือพิจารณาเฉพาะอักขระ 72 ตัวแรกของรหัสผ่าน?

ข้อดี

  • ผู้ใช้ไม่สามารถเข้าสู่ระบบโดยป้อนเพียง 72 อักขระแรก
  • คุณสามารถเพิ่มพริกไทยได้โดยไม่เกินขีด จำกัด อักขระ
  • ผลลัพธ์ของ hash_hmac อาจมีเอนโทรปีมากกว่ารหัสผ่าน
  • รหัสผ่านถูกแฮชโดยฟังก์ชันที่แตกต่างกันสองฟังก์ชัน

จุดด้อย

  • ใช้อักขระเพียง 64 ตัวในการสร้างแฮชปักเป้า


แก้ไข 1:คำถามนี้ตอบเฉพาะการรวม PHP ของปักเป้า / bcrypt ขอบคุณสำหรับความคิดเห็น!


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

2
การตัดทอนอักขระ 72 ตัวเป็นพื้นฐานของอัลกอริทึม Blowfish หรือเพียงแค่การใช้งาน PHP? IIRC Blowfish ยังใช้กับ (อย่างน้อยก็บางส่วน) เพื่อเข้ารหัสรหัสผ่านของผู้ใช้
Douglas B.Staple

3
ปัญหาอยู่ที่ Bcrypt ไม่ใช่ Blowfish ฉันสามารถสร้างปัญหานี้ซ้ำได้ด้วย Python และ Bcrypt เพียงอย่างเดียว
Blender

@Blender: ขอบคุณสำหรับความคิดเห็นและผลงานของคุณ ฉันไม่พบฟังก์ชันที่แตกต่างกันใน php สำหรับปักเป้าและ bcrypt และแม้ว่าจะเหมือนกัน แต่มันไม่สร้างความแตกต่างให้ฉันใน php หรือไม่? ฉันต้องการใช้ฟังก์ชัน php มาตรฐาน
Frederik Kammer

1
ดูกรอบการแฮชรหัสผ่าน PHPของ Openwall (PHPass) ด้วย พกพาและทนทานต่อการโจมตีรหัสผ่านของผู้ใช้ทั่วไป คนที่เขียนกรอบ (SolarDesigner) เป็นคนเดียวกับที่เขียนจอห์นเดอะริปเปอร์และนั่งเป็นผู้พิพากษาในรหัสผ่าน Hashing การแข่งขัน ดังนั้นเขาจึงรู้ดีเกี่ยวกับการโจมตีรหัสผ่าน
jww

คำตอบ:


137

ปัญหานี้เป็นปัญหาของเอนโทรปี มาเริ่มกันเลย:

เอนโทรปีต่อตัวละคร

จำนวนบิตของเอนโทรปีต่อไบต์คือ:

  • อักขระ Hex
    • บิต: 4
    • ค่า: 16
    • เอนโทรปีใน 72 อักขระ: 288 บิต
  • อัลฟา - ตัวเลข
    • บิต: 6
    • ค่านิยม: 62
    • เอนโทรปีใน 72 Chars: 432 บิต
  • สัญลักษณ์ "ทั่วไป"
    • บิต: 6.5
    • ค่านิยม: 94
    • เอนโทรปีใน 72 อักขระ: 468 บิต
  • ไบต์เต็ม
    • บิต: 8
    • ค่า: 255
    • เอนโทรปีใน 72 Chars: 576 บิต

ดังนั้นวิธีการแสดงของเราขึ้นอยู่กับประเภทของตัวละครที่เราคาดหวัง

ปัญหาแรก

ปัญหาแรกกับรหัสของคุณคือขั้นตอนแฮช"pepper"ของคุณกำลังแสดงอักขระเลขฐานสิบหก (เนื่องจากhash_hmac()ไม่ได้ตั้งค่าพารามิเตอร์ที่สี่เป็น)

ดังนั้นการแฮ็กพริกไทยของคุณจะทำให้คุณสามารถตัดเอนโทรปีสูงสุดที่มีให้กับรหัสผ่านได้อย่างมีประสิทธิภาพด้วยปัจจัย 2 (จาก 576 ถึง 288 บิตที่เป็นไปได้ )

ปัญหาที่สอง

อย่างไรก็ตามsha256ให้256บิตของเอนโทรปีในตอนแรกเท่านั้น ดังนั้นคุณจึงตัด 576 บิตที่เป็นไปได้ให้เหลือ 256 บิตได้อย่างมีประสิทธิภาพ ขั้นตอนแฮชของคุณ * ทันที * โดยคำจำกัดความมากจะสูญเสีย เอนโทรปีอย่างน้อย 50% ที่เป็นไปได้ในรหัสผ่าน

คุณสามารถแก้ปัญหานี้ได้บางส่วนโดยเปลี่ยนไปใช้SHA512ซึ่งคุณจะลดเอนโทรปีที่มีอยู่ได้ประมาณ 12% เท่านั้น แต่นั่นก็ยังคงเป็นความแตกต่างที่ไม่สำคัญ 12% นั้นลดจำนวนการเรียงสับเปลี่ยนลงหนึ่ง1.8e19เท่า นั่นเป็นจำนวนมาก ... และนั่นคือปัจจัยที่ทำให้มันลดลง ...

ปัญหาพื้นฐาน

ปัญหาพื้นฐานคือรหัสผ่านมีสามประเภทที่ยาวเกิน 72 อักขระ ผลกระทบที่ระบบรูปแบบนี้มีต่อพวกเขาจะแตกต่างกันมาก:

หมายเหตุ: จากตรงนี้ฉันสมมติว่าเรากำลังเปรียบเทียบกับระบบพริกไทยที่ใช้SHA512กับเอาต์พุตดิบ (ไม่ใช่ฐานสิบหก)

  • รหัสผ่านแบบสุ่มเอนโทรปีสูง

    นี่คือผู้ใช้ของคุณที่ใช้ตัวสร้างรหัสผ่านซึ่งจะสร้างจำนวนเงินให้กับคีย์ขนาดใหญ่สำหรับรหัสผ่าน เป็นแบบสุ่ม (สร้างขึ้นไม่ใช่โดยมนุษย์เลือก) และมีเอนโทรปีสูงต่ออักขระ ประเภทเหล่านี้กำลังใช้ไฮไบต์ (อักขระ> 127) และอักขระควบคุมบางตัว

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

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

  • รหัสผ่านสุ่มเอนโทรปีขนาดกลาง

    กลุ่มนี้กำลังใช้รหัสผ่านที่มีสัญลักษณ์ทั่วไป แต่ไม่มีไบต์สูงหรืออักขระควบคุม นี่คือรหัสผ่านที่คุณสามารถพิมพ์ได้

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

    ให้ฉันพูดอีกครั้ง สำหรับรหัสผ่านคลาสนี้คุณสามารถจัดเก็บอักขระได้อีก 6 ตัวก่อนที่เอนโทรปีจะหมด

  • รหัสผ่านแบบไม่สุ่มเอนโทรปีต่ำ

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

    สำหรับกลุ่มนี้คุณสามารถปลดล็อกเอนโทรปีได้มากขึ้น (ไม่ได้สร้างขึ้น แต่อนุญาตให้ใส่รหัสผ่าน bcrypt ได้มากขึ้น) โดยการแฮช จุดคุ้มทุนอยู่ที่ประมาณ 223 อักขระก่อนที่คุณจะหมดเอนโทรปี

    ค่อยว่ากันอีกที สำหรับรหัสผ่านประเภทนี้การแฮชล่วงหน้าช่วยเพิ่มความปลอดภัยอย่างมาก

กลับสู่โลกแห่งความจริง

การคำนวณเอนโทรปีประเภทนี้ไม่ได้มีความสำคัญมากนักในโลกแห่งความเป็นจริง สิ่งที่สำคัญคือการคาดเดาเอนโทรปี นั่นคือสิ่งที่ส่งผลโดยตรงต่อสิ่งที่ผู้โจมตีสามารถทำได้ นั่นคือสิ่งที่คุณต้องการเพิ่มสูงสุด

แม้ว่าจะมีงานวิจัยเพียงเล็กน้อยที่คาดเดาเอนโทรปีได้ แต่ก็มีบางประเด็นที่ฉันอยากจะชี้ให้เห็น

โอกาสของการสุ่มเดา 72 ตัวอักษรที่ถูกต้องในแถวเป็นอย่างยิ่งต่ำ คุณมีแนวโน้มที่จะชนะลอตเตอรี Powerball 21 ครั้งมากกว่าที่จะเกิดการปะทะกันนี้ ... นั่นคือจำนวนที่มากที่เรากำลังพูดถึง

แต่เราอาจไม่สะดุดกับมันในทางสถิติ ในกรณีของวลีโอกาสที่อักขระ 72 ตัวแรกจะเหมือนกันนั้นสูงกว่ารหัสผ่านแบบสุ่ม แต่ก็ยังต่ำอยู่เล็กน้อย (คุณมีแนวโน้มที่จะชนะลอตเตอรี Powerball มากกว่า 5 ครั้งโดยอิงจาก 2.3 บิตต่อตัวละคร)

ในทางปฏิบัติ

ในทางปฏิบัติมันไม่สำคัญจริงๆ โอกาสที่คนจะเดาอักขระ 72 ตัวแรกถูกต้องโดยที่ตัวหลังสร้างความแตกต่างอย่างมีนัยสำคัญนั้นต่ำมากจนไม่น่ากังวล ทำไม?

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

ลองมาเป็นตัวอย่าง ลองมาอ้างจากพระคัมภีร์ (เพียงเพราะเป็นแหล่งที่มาของข้อความขนาดยาวทั่วไปไม่ใช่ด้วยเหตุผลอื่นใด):

อย่าโลภบ้านของเพื่อนบ้าน อย่าโลภภรรยาของเพื่อนบ้านหรือทาสหรือสาวใช้ของเขาวัวหรือลาของเขาหรือสิ่งใด ๆ ที่เป็นของเพื่อนบ้านของคุณ

นั่นคือ 180 อักขระ ตัวละครที่ 73 คือในครั้งที่สองg neighbor'sหากคุณเดาได้มากขนาดนั้นคุณอาจจะไม่หยุดneiแต่จะดำเนินการต่อในส่วนที่เหลือ (เนื่องจากเป็นวิธีที่น่าจะใช้รหัสผ่าน) ดังนั้น "แฮช" ของคุณจึงไม่ได้เพิ่มมากนัก

BTW: ฉันไม่สนับสนุนการใช้คำพูดในพระคัมภีร์อย่างแน่นอน ในความเป็นจริงตรงกันข้ามแน่นอน

สรุป

คุณจะไม่ช่วยคนที่ใช้รหัสผ่านยาว ๆ ด้วยการแฮชก่อน บางกลุ่มคุณช่วยได้แน่นอน บางอย่างคุณสามารถทำร้ายได้แน่นอน

แต่ท้ายที่สุดแล้วไม่มีสิ่งใดที่สำคัญเกินไป ตัวเลขที่เราจะจัดการกับเป็นเพียงWAYสูงเกินไป ความแตกต่างของเอนโทรปีจะไม่มากนัก

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

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

นั่นคือ 0.02 ดอลลาร์ของฉันเป็นอย่างน้อย (หรืออาจมากกว่า 0.02 ดอลลาร์) ...

เท่าที่ใช้พริกไทย "ลับ":

ไม่มีงานวิจัยเกี่ยวกับการป้อนฟังก์ชันแฮชลงใน bcrypt อย่างแท้จริง ดังนั้นจึงไม่มีความชัดเจนที่ดีที่สุดหากการป้อนแฮช "peppered" ลงใน bcrypt จะทำให้เกิดช่องโหว่ที่ไม่รู้จัก (เรารู้ว่าการทำเช่นhash1(hash2($value))นี้อาจทำให้เกิดช่องโหว่ที่สำคัญเกี่ยวกับการต้านทานการชนและการโจมตีก่อนภาพ)

เมื่อพิจารณาว่าคุณกำลังพิจารณาจัดเก็บคีย์ลับ ("พริกไทย") อยู่แล้วทำไมไม่ใช้มันในแบบที่ศึกษาและเข้าใจกันดีล่ะ ทำไมไม่เข้ารหัสแฮชก่อนจัดเก็บ?

โดยทั่วไปหลังจากที่คุณแฮชรหัสผ่านแล้วให้ป้อนเอาต์พุตแฮชทั้งหมดลงในอัลกอริทึมการเข้ารหัสที่แข็งแกร่ง จากนั้นจัดเก็บผลลัพธ์ที่เข้ารหัส

ตอนนี้การโจมตีด้วย SQL-Injection จะไม่รั่วไหลอะไรที่เป็นประโยชน์เพราะพวกเขาไม่มีรหัสตัวเลข และหากกุญแจรั่วผู้โจมตีจะไม่ดีไปกว่าถ้าคุณใช้แฮชธรรมดา (ซึ่งสามารถพิสูจน์ได้บางอย่างที่มีพริกไทย

หมายเหตุ: หากคุณเลือกที่จะทำสิ่งนี้ให้ใช้ไลบรารี สำหรับ PHP ขอแนะนำZend\Cryptแพ็คเกจของ Zend Framework 2 ที่จริงแล้วเป็นสิ่งเดียวที่ฉันแนะนำ ณ จุดปัจจุบันนี้ ได้รับการตรวจสอบอย่างดีเยี่ยมและทำการตัดสินใจทั้งหมดสำหรับคุณ (ซึ่งเป็นสิ่งที่ดีมาก) ...

สิ่งที่ต้องการ:

use Zend\Crypt\BlockCipher;

public function createHash($password) {
    $hash = password_hash($password, PASSWORD_BCRYPT, ["cost"=>$this->cost]);

    $blockCipher = BlockCipher::factory('mcrypt', array('algo' => 'aes'));
    $blockCipher->setKey($this->key);
    return $blockCipher->encrypt($hash);
}

public function verifyHash($password, $hash) {
    $blockCipher = BlockCipher::factory('mcrypt', array('algo' => 'aes'));
    $blockCipher->setKey($this->key);
    $hash = $blockCipher->decrypt($hash);

    return password_verify($password, $hash);
}

และเป็นประโยชน์เพราะคุณใช้อัลกอริทึมทั้งหมดในรูปแบบที่เข้าใจดีและศึกษามาอย่างดี (อย่างน้อยที่สุด) จำไว้ว่า:

ไม่ว่าใครก็ตามตั้งแต่มือสมัครเล่นที่ไร้เดียงสาไปจนถึงนักเข้ารหัสที่เก่งที่สุดสามารถสร้างอัลกอริทึมที่ตัวเขาเองไม่สามารถทำลายได้


6
ขอบคุณมากสำหรับคำตอบโดยละเอียดนี้ สิ่งนี้ช่วยฉันได้จริงๆ!
Frederik Kammer

1
คำชมของฉันสำหรับคำตอบนี้ แม้ว่าจะมีการเลือก nit-pick เพียงเล็กน้อย แต่ก็เป็นผู้ใช้ส่วนใหญ่ที่ใช้รหัสผ่านคำและอนุพันธ์ที่อ่อนแอมากที่มีอยู่ในพจนานุกรมสำหรับการถอดรหัสรหัสผ่านพริกไทยจะช่วยปกป้องพวกเขาอย่างอิสระจากคำถามเอนโทรฟี่ เพื่อหลีกเลี่ยงการสูญเสียเอนโทรฟีคุณสามารถเชื่อมรหัสผ่านและพริกไทยเข้าด้วยกัน อย่างไรก็ตามคำแนะนำของคุณเกี่ยวกับการเข้ารหัสค่าแฮชน่าจะเป็นทางออกที่ดีที่สุดในการเพิ่มความลับฝั่งเซิร์ฟเวอร์
martinstoeckli

2
@martinstoeckli: ปัญหาของฉันเกี่ยวกับแนวคิดเรื่องพริกไทยไม่ได้อยู่ที่คุณค่าของมัน ในการประยุกต์ใช้ "พริกไทย" จะเข้าสู่ดินแดนที่ไม่มีใครสังเกตเห็นในแง่ของอัลกอริทึมการเข้ารหัส นั่นไม่ใช่เรื่องดี แต่ฉันเชื่อว่าการเข้ารหัสลับควรรวมเข้าด้วยกันในแบบที่ออกแบบมาให้ไปด้วยกัน โดยพื้นฐานแล้วแนวคิดหลักของพริกไทยฟังอยู่ในหูของฉันเช่นบางคนที่ไม่รู้อะไรเลยเกี่ยวกับการเข้ารหัสกล่าวว่า"แฮชมากกว่านี้ดีกว่าเรามีเกลือพริกไทยก็ดีเหมือนกัน!" . ฉันแค่อยากจะมีการทดสอบที่ง่ายกว่าทดสอบและตรงไปตรงมามากกว่า
ircmaxell

@ircmaxell - ใช่ฉันรู้มุมมองของคุณและฉันเห็นด้วยตราบใดที่ค่าแฮชจะถูกเข้ารหัสในภายหลัง หากคุณไม่ทำตามขั้นตอนเพิ่มเติมนี้การโจมตีด้วยพจนานุกรมจะเปิดเผยรหัสผ่านที่ไม่รัดกุมมากเกินไปแม้ว่าจะมีอัลกอริทึมแฮชที่ดีก็ตาม
martinstoeckli

1
@martinstoeckli: ฉันไม่เห็นด้วยที่นั่น การเก็บความลับไม่ใช่เรื่องเล็กน้อยที่ต้องทำ แต่ถ้าคุณใช้ bcrypt ด้วยต้นทุนที่ดี (12 วันนี้) รหัสผ่านทั้งหมดยกเว้นระดับที่อ่อนแอที่สุดจะปลอดภัย (พจนานุกรมและรหัสผ่านเล็กน้อยเป็นรหัสที่อ่อนแอ) ดังนั้นฉันจึงอยากแนะนำให้ผู้คนให้ความสำคัญกับการให้ความรู้แก่ผู้ใช้ด้วยเครื่องวัดความแรงและทำให้พวกเขาใช้รหัสผ่านที่ดีขึ้นตั้งแต่แรก ...
ircmaxell

5

รหัสผ่าน Peppering เป็นสิ่งที่ดีอย่างแน่นอน แต่เรามาดูเหตุผลกันดีกว่า

อันดับแรกเราควรตอบคำถามเมื่อพริกไทยช่วยได้จริง พริกไทยป้องกันรหัสผ่านเท่านั้นตราบใดที่ยังเป็นความลับดังนั้นหากผู้โจมตีสามารถเข้าถึงเซิร์ฟเวอร์ได้ก็จะไม่มีประโยชน์ การโจมตีที่ง่ายกว่ามากคือ SQL-injection ซึ่งช่วยให้สามารถเข้าถึงฐานข้อมูลได้ (ไปยังค่าแฮชของเรา) ฉันเตรียมการสาธิตการฉีด SQLเพื่อแสดงให้เห็นว่ามันง่ายแค่ไหน (คลิกลูกศรถัดไปเพื่อเตรียม อินพุต)

แล้วพริกไทยช่วยอะไรได้จริง? ตราบใดที่พริกไทยยังคงเป็นความลับมันจะช่วยปกป้องรหัสผ่านที่อ่อนแอจากการโจมตีของพจนานุกรม 1234จากนั้นรหัสผ่านจะกลายเป็นอย่าง1234-p*deDIUZeRweretWy+.Oนั้น รหัสผ่านนี้ไม่เพียง แต่ยาวขึ้นเท่านั้น แต่ยังมีอักขระพิเศษและจะไม่เป็นส่วนหนึ่งของพจนานุกรมใด ๆ

ตอนนี้เราสามารถประมาณรหัสผ่านที่ผู้ใช้ของเราจะใช้อาจมีผู้ใช้จำนวนมากขึ้นที่จะป้อนรหัสผ่านที่ไม่รัดกุมเนื่องจากมีผู้ใช้ที่มีรหัสผ่านระหว่าง 64-72 ตัวอักษร (ซึ่งจะหายากมาก)

อีกจุดหนึ่งคือช่วงสำหรับการบังคับเดรัจฉาน ฟังก์ชันแฮช sha256 จะส่งคืนเอาต์พุต 256 บิตหรือชุดค่าผสม 1.2E77 ซึ่งเป็นวิธีที่มากเกินไปสำหรับการบังคับแบบเดรัจฉานแม้กระทั่งสำหรับ GPU (ถ้าฉันคำนวณอย่างถูกต้องสิ่งนี้จะต้องใช้เวลาประมาณ2E61 ปีสำหรับ GPU ในปี 2013) ดังนั้นเราจึงไม่ได้รับข้อเสียที่แท้จริงในการใช้พริกไทย เนื่องจากค่าแฮชไม่เป็นระบบคุณจึงไม่สามารถเร่งความเร็วในการบังคับเดรัจฉานด้วยรูปแบบทั่วไปได้

ป.ล. เท่าที่ฉันรู้ขีด จำกัด 72 อักขระนั้นเฉพาะสำหรับอัลกอริทึมของ BCrypt เอง คำตอบที่ดีที่สุดที่ฉันพบก็คือนี้

PPS ฉันคิดว่าตัวอย่างของคุณมีข้อบกพร่องคุณไม่สามารถสร้างแฮชด้วยความยาวของรหัสผ่านแบบเต็มและตรวจสอบด้วยรหัสที่ถูกตัดทอน คุณอาจหมายถึงการใช้พริกไทยในลักษณะเดียวกับการสร้างแฮชและสำหรับการตรวจสอบแฮช


เกี่ยวกับ PPS ของคุณฉันสามารถเพียงแค่พูดว่า: trueใช่เขาสามารถตรวจสอบรหัสผ่านตัดทอนกับกัญชาของที่ไม่ใช่ตัดทอนหนึ่งและยังคงได้รับ นั่นคือสิ่งที่คำถามนี้เป็นข้อมูลเกี่ยวกับ ดูด้วยตัวคุณเอง: viper-7.com/RLKFnB
Sliq

@ Panique - ปัญหาไม่ใช่การคำนวณแฮช BCrypt แต่เป็น HMAC มาก่อน สำหรับการสร้างแฮช SHA OP จะใช้รหัสผ่านแบบเต็มความยาวและใช้ผลลัพธ์เป็นอินพุตสำหรับ BCrypt สำหรับการตรวจสอบเขาตัดทอนรหัสผ่านก่อนคำนวณแฮช SHA จากนั้นใช้ผลลัพธ์ที่แตกต่างอย่างสิ้นเชิงนี้เป็นอินพุตสำหรับ BCrypt HMAC ยอมรับอินพุตที่มีความยาวเท่าใดก็ได้
martinstoeckli

2

Bcrypt ใช้อัลกอริทึมตามอัลกอริทึมการตั้งค่าคีย์ Blowfish ที่มีราคาแพง

ขีด จำกัด รหัสผ่าน 56 ไบต์ที่แนะนำ (รวมถึงไบต์การสิ้นสุด null) สำหรับ bcrypt เกี่ยวข้องกับขีด จำกัด 448 บิตของคีย์ Blowfish ไบต์ใด ๆ ที่เกินขีด จำกัด นั้นจะไม่ถูกผสมลงในแฮชผลลัพธ์ ขีด จำกัด สัมบูรณ์ 72 ไบต์สำหรับรหัสผ่าน bcrypt จึงมีความเกี่ยวข้องน้อยกว่าเมื่อคุณพิจารณาผลกระทบที่แท้จริงของแฮชที่เป็นผลลัพธ์โดยไบต์เหล่านั้น

หากคุณคิดว่าปกติแล้วผู้ใช้ของคุณจะเลือกรหัสผ่านที่มีความยาวมากกว่า 55 ไบต์โปรดจำไว้ว่าคุณสามารถเพิ่มรอบของการยืดรหัสผ่านแทนได้เสมอเพื่อเพิ่มความปลอดภัยในกรณีที่ตารางรหัสผ่านละเมิด (แม้ว่าจะต้องมากเมื่อเทียบกับการเพิ่มพิเศษ อักขระ) หากสิทธิ์การเข้าถึงของผู้ใช้มีความสำคัญมากจนโดยปกติผู้ใช้จะต้องใช้รหัสผ่านที่ยาวมากการหมดอายุของรหัสผ่านก็ควรสั้นเช่นกันเช่น 2 สัปดาห์ ซึ่งหมายความว่ารหัสผ่านมีโอกาสน้อยมากที่จะยังคงใช้ได้ในขณะที่แฮ็กเกอร์ลงทุนทรัพยากรของตนในการเอาชนะปัจจัยด้านงานที่เกี่ยวข้องกับการทดสอบรหัสผ่านทดลองแต่ละรหัสเพื่อดูว่าจะสร้างแฮชที่ตรงกัน

แน่นอนว่าในกรณีของตารางรหัสผ่านไม่ได้ถูกละเมิดเราควรอนุญาตให้แฮกเกอร์พยายามเดารหัสผ่าน 55 ไบต์ของผู้ใช้อย่างมากที่สุดสิบครั้งก่อนที่จะล็อกบัญชีของผู้ใช้;)

หากคุณตัดสินใจที่จะแฮชรหัสผ่านที่ยาวกว่า 55 ไบต์ล่วงหน้าคุณควรใช้ SHA-384 เนื่องจากมีเอาต์พุตที่ใหญ่ที่สุดโดยไม่เกินขีด จำกัด


1
"การหมดอายุของรหัสผ่านควรสั้นเช่น 2 สัปดาห์" ของ "รหัสผ่านที่ยาวมาก" จริง ๆ แล้วทำไมต้องกังวลกับการบันทึกรหัสผ่านเพียงแค่ใช้การรีเซ็ตรหัสผ่านทุกครั้ง อย่างจริงจังนั่นเป็นวิธีแก้ปัญหาที่ไม่ถูกต้องให้ย้ายไปที่การตรวจสอบสิทธิ์สองปัจจัยด้วยโทเค็น
zaph

ขอบคุณ @zaph. คุณช่วยชี้ให้ฉันดูตัวอย่างได้ไหม ฟังดูน่าสนใจ
ฟิลิป

[DRAFT NIST Special Publication 800-63B Digital Authentication Guideline] ( pages.nist.gov/800-63-3/sp800-63b.html ), 5.1.1.2 จำลับ Verifiers: Verifiers ไม่ควรต้องจดจำความลับจะมีการเปลี่ยนแปลงโดยพลการ (เช่นเป็นระยะ) นอกจากนี้โปรดดูToward Better Password Requirements by Jim Fenton
zaph

1
สิ่งนี้ก็คือยิ่งผู้ใช้จำเป็นต้องเปลี่ยนรหัสผ่านบ่อยเท่าไหร่ตัวเลือกรหัสผ่านที่แย่ที่สุดก็จะลดความปลอดภัยลง ผู้ใช้มีรหัสผ่านที่จำได้ดีจำนวน จำกัด และหมดลงไม่ว่าจะเลือกรหัสผ่านที่ไม่ดีจริง ๆ หรือเขียนลงในโน้ตโพสต์อิทที่ติดอยู่ที่ด้านล่างของแป้นพิมพ์เป็นต้น
zaph
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.