การปฏิเสธความรับผิด : คำตอบนี้ถูกเขียนในปี 2008
ตั้งแต่นั้นมา PHP ได้ให้เราpassword_hash
และpassword_verify
และตั้งแต่การแนะนำพวกเขาพวกเขาเป็นวิธีการแฮชรหัสผ่านและตรวจสอบที่แนะนำ
ทฤษฎีของคำตอบยังคงอ่านได้ดี
TL; DR
Don'ts
- อย่า จำกัด สิ่งที่ผู้ใช้สามารถป้อนรหัสผ่านได้ คนโง่เท่านั้นที่ทำสิ่งนี้
- อย่าจำกัดความยาวของรหัสผ่าน หากผู้ใช้ของคุณต้องการประโยคที่มี supercalifragilisticexpialidocious อยู่ในนั้นอย่าป้องกันพวกเขาจากการใช้มัน
- อย่าดึงหรือหนี HTML และอักขระพิเศษในรหัสผ่าน
- อย่าเก็บรหัสผ่านของผู้ใช้เป็นข้อความธรรมดา
- อย่าส่งอีเมลรหัสผ่านให้กับผู้ใช้ของคุณยกเว้นเมื่อพวกเขาทำรหัสผ่านหายและคุณส่งรหัสชั่วคราว
- ไม่เคยบันทึกรหัสผ่านในลักษณะใด ๆ
- อย่าแฮรหัสผ่านด้วยSHA1หรือ MD5 หรือแม้แต่ SHA256! แครกเกอร์ที่ทันสมัยสามารถมีแฮ็ชได้มากกว่า 60 และ 180 พันล้านต่อวินาที
- อย่าผสมbcrypt และกับเอาต์พุตดิบของ hash ()ไม่ว่าจะใช้ hex output หรือ base64_encode (สิ่งนี้ใช้กับอินพุตใด ๆ ที่อาจมีการโกง
\0
ในซึ่งสามารถลดความปลอดภัยอย่างจริงจัง)
Dos
- ใช้ scrypt เมื่อคุณสามารถ; bcrypt หากคุณไม่สามารถ
- ใช้ PBKDF2 หากคุณไม่สามารถใช้ bcrypt หรือ scrypt โดยที่มีแฮช SHA2
- รีเซ็ตรหัสผ่านของทุกคนเมื่อฐานข้อมูลถูกบุกรุก
- ใช้ความยาวต่ำสุดที่เหมาะสม 8-10 ตัวอักษรและต้องมีตัวอักษรตัวพิมพ์ใหญ่อย่างน้อย 1 ตัวอักษรตัวพิมพ์เล็ก 1 ตัวตัวเลขและสัญลักษณ์ วิธีนี้จะช่วยปรับปรุงรหัสผ่านของเอนโทรปีทำให้ยากต่อการถอดรหัส (ดูหัวข้อ "อะไรคือรหัสผ่านที่ดี?" เพื่อการอภิปรายบางส่วน)
ทำไมต้องใช้รหัสผ่านแฮช
วัตถุประสงค์ของการแฮ็รหัสผ่านนั้นง่ายมาก: การป้องกันการเข้าถึงบัญชีผู้ใช้ที่เป็นอันตรายโดยการทำให้ฐานข้อมูลเสียหาย ดังนั้นเป้าหมายของการแฮ็กรหัสผ่านคือการยับยั้งแฮ็กเกอร์หรือแครกเกอร์โดยใช้เวลาหรือเงินมากเกินไปในการคำนวณรหัสผ่านแบบข้อความธรรมดา และเวลา / ค่าใช้จ่ายเป็นตัวยับยั้งที่ดีที่สุดในคลังแสงของคุณ
อีกเหตุผลที่คุณต้องการแฮชที่ดีและมีประสิทธิภาพในบัญชีผู้ใช้คือให้เวลาคุณพอที่จะเปลี่ยนรหัสผ่านทั้งหมดในระบบ หากฐานข้อมูลของคุณถูกบุกรุกคุณจะต้องใช้เวลาในการล็อคระบบอย่างน้อยถ้าไม่เปลี่ยนรหัสผ่านทุกครั้งในฐานข้อมูล
Jeremiah Grossman, CTO ของ Whitehat Security ระบุไว้ในบล็อก White Hat Securityหลังจากการกู้คืนรหัสผ่านเมื่อเร็ว ๆ นี้ซึ่งจำเป็นต้องใช้การป้องกันด้วยรหัสผ่านของเขา:
ที่น่าสนใจในการใช้ชีวิตในฝันร้ายนี้ฉันได้เรียนรู้มากมายที่ฉันไม่รู้เกี่ยวกับการถอดรหัสรหัสผ่านการจัดเก็บและความซับซ้อน ฉันมาชื่นชมว่าทำไมการจัดเก็บรหัสผ่านจึงมีความสำคัญมากกว่าความซับซ้อนของรหัสผ่าน หากคุณไม่ทราบวิธีการจัดเก็บรหัสผ่านของคุณสิ่งที่คุณสามารถทำได้คือความซับซ้อน นี่อาจเป็นความรู้ทั่วไปเกี่ยวกับรหัสผ่านและข้อดีของการเข้ารหัสลับ แต่สำหรับผู้เชี่ยวชาญด้านความมั่นคงสารสนเทศโดยเฉลี่ยหรือผู้เชี่ยวชาญด้านความปลอดภัยเว็บฉันสงสัยอย่างมาก
(ของฉันเน้น)
อะไรที่ทำให้รหัสผ่านที่ดีอยู่ดี
เอนโทรปี (ไม่ใช่ว่าฉันสมัครรับมุมมองของ Randall อย่างเต็มที่)
กล่าวโดยสรุปเอนโทรปีคือความผันแปรภายในรหัสผ่าน เมื่อรหัสผ่านเป็นอักษรโรมันตัวพิมพ์เล็กเท่านั้นนั่นเป็นเพียง 26 ตัวอักษร นั่นไม่แตกต่างกันมาก รหัสผ่านที่เป็นตัวเลขและตัวอักษรจะดีกว่าโดยมี 36 ตัวอักษร แต่การอนุญาตให้ใช้ตัวพิมพ์เล็กและใหญ่ด้วยสัญลักษณ์มีความยาวประมาณ 96 อักขระ มันดีกว่าแค่ตัวอักษร ปัญหาหนึ่งคือการทำให้รหัสผ่านของเราเป็นที่น่าจดจำเราได้ใส่รูปแบบซึ่งช่วยลดการใช้พลังงานเอนโทรปี อ๊ะ!
รหัสผ่านเอนโทรปีถูกประมาณได้อย่างง่ายดาย การใช้ช่วงเต็มของอักขระ ASCII (ประมาณ 96 อักขระที่พิมพ์ได้) ให้เอนโทรปีของ 6.6 ต่อตัวอักษรซึ่งที่ 8 ตัวอักษรสำหรับรหัสผ่านยังต่ำเกินไป (เอนโทรปี 52.679 บิต) เพื่อความปลอดภัยในอนาคต แต่ข่าวดีก็คือ: รหัสผ่านที่ยาวขึ้นและรหัสผ่านที่มีอักขระ Unicode เพิ่มรหัสผ่านของเอนโทรปีและทำให้แตกได้ยากขึ้น
มีการถกเถียงเรื่องรหัสผ่านเอนโทรปีบนไซต์Crypto StackExchangeอีกต่อไป การค้นหาของ Google ที่ดีจะทำให้ได้ผลลัพธ์จำนวนมาก
ในความคิดเห็นที่ฉันได้พูดคุยกับ @popnoodles ซึ่งชี้ให้เห็นว่าการบังคับใช้นโยบายรหัสผ่านของความยาว X ด้วยตัวอักษรตัวเลขสัญลักษณ์และอื่น ๆ จำนวนมาก X สามารถลดเอนโทรปีได้ด้วยการทำให้รูปแบบรหัสผ่านสามารถคาดเดาได้มากขึ้น ฉันเห็นด้วย. Randomess อย่างสุ่มที่สุดเท่าที่จะทำได้เป็นวิธีที่ปลอดภัย แต่น่าจดจำน้อยที่สุดเสมอ
เท่าที่ฉันสามารถบอกได้การสร้างรหัสผ่านที่ดีที่สุดในโลกคือ Catch-22 ไม่ว่าจะเป็นที่น่าจดจำคาดเดาได้สั้นเกินไปตัวอักษรยูนิโค้ดมากเกินไป (ยากที่จะพิมพ์บนอุปกรณ์ Windows / Mobile) ยาวเกินไป ฯลฯ ไม่มีรหัสผ่านที่ดีพอสำหรับวัตถุประสงค์ของเราดังนั้นเราจึงต้องปกป้องพวกเขาราวกับว่าพวกเขา อยู่ในฟอร์ทน็อกซ์
ปฏิบัติที่ดีที่สุด
Bcrypt และscryptเป็นแนวทางปฏิบัติที่ดีที่สุดในปัจจุบัน Scryptจะดีกว่า bcrypt ในเวลา แต่มันยังไม่เห็นว่าการยอมรับเป็นมาตรฐานโดย Linux / Unix หรือโดย webservers และยังไม่มีการตรวจสอบขั้นตอนวิธีเชิงลึกที่โพสต์ แต่ถึงกระนั้นอนาคตของอัลกอริทึมก็ดูสดใส หากคุณทำงานกับ Ruby มีscrypt gemที่จะช่วยคุณได้และตอนนี้ Node.js มีแพ็คเกจscryptของตัวเอง คุณสามารถใช้ Scrypt ใน PHP ผ่านส่วนขยายScryptหรือส่วนขยายLibsodium (ทั้งสองมีให้บริการใน PECL)
ฉันขอแนะนำให้อ่านเอกสารสำหรับฟังก์ชัน cryptหากคุณต้องการเข้าใจวิธีการใช้ bcrypt หรือค้นหาwrapper ที่ดี หรือใช้สิ่งที่ต้องการเช่นPHPASSสำหรับการใช้งานแบบดั้งเดิมมากขึ้น ฉันแนะนำ bcrypt อย่างน้อย 12 รอบถ้าไม่ใช่ 15 ถึง 18
ฉันเปลี่ยนใจเกี่ยวกับการใช้ bcrypt เมื่อฉันเรียนรู้ว่า bcrypt ใช้กำหนดการสำคัญของ blowfish เท่านั้นพร้อมกับกลไกต้นทุนผันแปร หลังช่วยให้คุณเพิ่มค่าใช้จ่ายในการบังคับใช้รหัสผ่านโดยเพิ่มตารางคีย์ราคาแพงของปลาปักเป้า
การปฏิบัติโดยเฉลี่ย
ฉันแทบจะนึกภาพสถานการณ์นี้ไม่ได้อีกแล้ว PHPASSรองรับ PHP 3.0.18 ถึง 5.3 ดังนั้นจึงสามารถใช้งานได้ในเกือบทุกการติดตั้งเท่าที่จะเป็นไปได้และควรใช้หากคุณไม่ทราบว่าระบบของคุณรองรับ bcrypt หรือไม่
แต่สมมติว่าคุณไม่สามารถใช้ bcrypt หรือ PHPASS ได้เลย ถ้าเช่นนั้นจะเป็นอย่างไร
ลองใช้PDKBF2กับจำนวนรอบสูงสุดที่สภาพแวดล้อม / แอปพลิเคชัน / การรับรู้ของผู้ใช้ของคุณสามารถทนได้ จำนวนต่ำสุดที่ฉันแนะนำคือ 2500 รอบ นอกจากนี้ตรวจสอบให้แน่ใจว่าใช้hash_hmac ()หากสามารถทำให้การดำเนินการทำซ้ำยากขึ้น
แนวทางปฏิบัติในอนาคต
มาใน PHP 5.5 เป็นรหัสผ่านห้องสมุดคุ้มครองเต็มรูปแบบที่ abstracts ออกไปความเจ็บปวดของการทำงานกับ bcrypt ใด ๆ ในขณะที่พวกเราส่วนใหญ่ติดอยู่กับ PHP 5.2 และ 5.3 ในสภาพแวดล้อมที่พบบ่อยที่สุดโดยเฉพาะโฮสต์ที่ใช้ร่วมกัน @ircmaxell ได้สร้างเลเยอร์ที่เข้ากันได้สำหรับ API ที่กำลังจะมาซึ่งสามารถใช้งานร่วมกับ PHP 5.3.7 ได้
สรุปการเข้ารหัสและข้อสงวนสิทธิ์
กำลังการคำนวณที่จำเป็นในการถอดรหัสรหัสผ่านที่แฮชไม่มีอยู่จริง วิธีเดียวที่คอมพิวเตอร์จะ "ถอดรหัส" รหัสผ่านคือการสร้างรหัสใหม่และจำลองอัลกอริทึมการแฮชที่ใช้เพื่อรักษาความปลอดภัย ความเร็วของการแฮชนั้นสัมพันธ์กับความสามารถในการถูกบังคับแบบไร้เดียงสา อัลกอริธึมแฮชส่วนใหญ่สามารถทำให้ขนานได้อย่างง่ายดายเพื่อให้ทำงานได้เร็วขึ้น นี่คือเหตุผลที่แผนการแพงเช่น bcrypt และ scrypt มีความสำคัญมาก
คุณไม่อาจล่วงรู้ภัยคุกคามทั้งหมดหรือลู่ทางของการโจมตีและเพื่อให้คุณจะต้องทำให้ความพยายามที่ดีที่สุดของคุณเพื่อปกป้องผู้ใช้ของคุณขึ้นด้านหน้า ถ้าคุณทำไม่ได้แล้วคุณก็อาจจะพลาดความจริงที่ว่าคุณกำลังถูกโจมตีจนกว่าจะสายเกินไป ... และคุณต้องรับผิด เพื่อหลีกเลี่ยงสถานการณ์นั้นให้ทำหวาดระแวงเพื่อเริ่มต้น โจมตีซอฟต์แวร์ของคุณเอง (ภายใน) และพยายามขโมยข้อมูลรับรองของผู้ใช้หรือแก้ไขบัญชีของผู้ใช้รายอื่นหรือเข้าถึงข้อมูลของพวกเขา หากคุณไม่ทดสอบความปลอดภัยของระบบคุณจะไม่สามารถตำหนิใครได้นอกจากตัวคุณเอง
สุดท้าย: ฉันไม่ใช่นักเขียนรหัส สิ่งที่ฉันได้พูดคือความคิดเห็นของฉัน แต่ฉันคิดว่ามันขึ้นอยู่กับสามัญสำนึกที่ดีของ ol ... และการอ่านจำนวนมาก จำไว้ว่าให้หวาดระแวงให้มากที่สุดทำให้สิ่งที่ยากแก่การบุกรุกมากที่สุดจากนั้นถ้าคุณยังกังวลให้ติดต่อแฮกเกอร์หมวกขาวหรือผู้เข้ารหัสเพื่อดูสิ่งที่พวกเขาพูดเกี่ยวกับรหัส / ระบบของคุณ