Score:1

ฟังก์ชัน password_verify() รับเกลือจากรหัสผ่านที่จัดเก็บไว้ในฐานข้อมูลอย่างไร

ธง sg

ฉันกำลังสร้างแบบฟอร์มลงทะเบียนและลงชื่อเข้าใช้อย่างง่ายโดยใช้ PHP ในการลงทะเบียน ฉันสร้างแฮชโดยใช้ฟังก์ชัน password_hash() แล้วเก็บไว้ในฐานข้อมูล ตอนที่ลงชื่อเข้าใช้ เริ่มแรกสิ่งที่ฉันทำคือสร้างแฮชใหม่โดยใช้ฟังก์ชัน password_hash() อีกครั้ง แล้วเปรียบเทียบกับแฮชรหัสผ่านที่เก็บไว้

สิ่งนี้ล้มเหลวตลอดเวลา เพราะอย่างที่ฉันเข้าใจในตอนนี้ เกลือใหม่จะถูกใช้ทุกครั้งที่คุณสร้างรหัสผ่านแฮชโดยใช้ฟังก์ชัน password_hash() หลังจากการค้นคว้า ฉันรู้ว่าควรใช้ฟังก์ชัน PHP password_verify(<plain_text_password>,<password_fetched_from_DB>)

สิ่งที่ฉันไม่เข้าใจคือทำไมฟังก์ชัน password_verify ถึงรู้ค่าเกลือที่ใช้ก่อนหน้านี้ตอนสมัคร หากไม่รู้จักเกลือ ดังนั้น password_verify ก็ควรล้มเหลวเช่นเดียวกับฟังก์ชัน password_hash เมื่อใช้สำหรับการเปรียบเทียบ

ฉันอ่านเกี่ยวกับเรื่องนี้เพิ่มเติมและสิ่งที่ฉันได้รู้ก็คือ เมื่อใช้ฟังก์ชัน password_hash() เพื่อสร้างแฮช มันจะเก็บค่าเกลือไว้ในแฮชด้วย? ตัวอย่างเช่น หากแฮชที่สร้างขึ้นเป็น abcde12345 ค่าเกลือจะเป็น 12345 ได้หรือไม่

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

kelalaka avatar
in flag
คุณอ่าน [ไซต์ PHP](https://www.php.net/manual/en/function.password-hash.php) ครบถ้วนหรือไม่ ในส่วนการคืนค่าหรือดูในส่วนนี้ คุณจะสังเกตเห็นว่า [password_verify()](https://www.php.net/manual/en/function.password-verify.php) ขอบคุณ ป้อนรหัสผ่านปัจจุบันและแฮชที่เก็บไว้ และส่งคืน T/F !
Score:2
ธง si

ผลลัพธ์ของฟังก์ชันการแฮชรหัสผ่านปกติใดๆ ประกอบด้วยการตั้งค่าความยาก เกลือ และการย่อยของรหัสผ่าน ซึ่งเข้ารหัสเป็นบางรูปแบบที่ฟังก์ชันการแฮชรหัสผ่านระบุ ฟังก์ชันการตรวจสอบต้องการรูปแบบเดียวกัน และเพียงแค่อ่านค่าเกลือออกมา เว็บไซต์นี้ มีคำอธิบายที่ดีสำหรับฟังก์ชันแฮช Argon2 ตัวอย่างเช่น สำหรับ argon2id (ตัวเลือกที่แนะนำสำหรับ PHP password_hash) ที่มีรหัสผ่าน 12345, salt qwertyuiop, 1 การวนซ้ำ, 1024 หน่วยความจำ, ความยาวแฮช 32, ความขนาน 1 เอาต์พุตคือ $argon2id$v=19$m=1024,t=1,p=1$cXdlcnR5dWlvcA$dSEO3lF0tmBRi3/HZFZqPJGv38CW35xf9Fcs+8ti0yk

คุณสามารถดูพารามิเตอร์ต่างๆ โดยคั่นด้วย $ สัญญาณ

Z3R0 avatar
jp flag
สวัสดี ฉันมีคำถามเกี่ยวกับเกลือเกลือที่จัดเก็บด้วยแฮชรหัสผ่านถูกแฮชด้วยหรืออยู่ในข้อความที่ชัดเจน? ตัวอย่างเช่น หากฉันมีแฮช 1234.abcde และ 1234 เกลือที่ส่งกลับโดย password_hash() แฮชเหมือนกันหรือเป็นข้อความธรรมดา ดังนั้นเมื่อฉันต้องการตรวจสอบแฮช ฉันเพียงแค่เพิ่ม 1234 เข้าไปในรหัสผ่านด้วยข้อความธรรมดาและเรียกใช้ฟังก์ชันการแฮชอีกครั้ง
SAI Peregrinus avatar
si flag
เกลือ (แน่นอน) อยู่ในข้อความที่ชัดเจน: มันไม่ใช่ความลับ (ตามคำจำกัดความของ "เกลือ") ในตัวอย่างแฮชที่ใช้ Argon2 มันคือ "cXdlcnR5dWlvcA" ซึ่งเข้ารหัส BASE64 แต่ไม่ได้เข้ารหัสอย่างแน่นอน จำเป็นต้องมีการเข้ารหัสเพื่อแปลงไบต์ที่กำหนดเอง (ซึ่งอาจรวม 0 ไบต์) เป็น "สตริง" ของอักขระ ASCII ที่พิมพ์ได้ซึ่งไม่สามารถรวม 0 ไบต์ได้
Score:1
ธง in

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

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

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

Z3R0 avatar
jp flag
สวัสดี ฉันมีคำถามเกี่ยวกับเกลือ เกลือที่จัดเก็บด้วยแฮชรหัสผ่านถูกแฮชด้วยหรืออยู่ในข้อความที่ชัดเจน? ตัวอย่างเช่น หากฉันมีแฮช 1234.abcde และ 1234 เกลือที่ส่งกลับโดย password_hash() แฮชเหมือนกันหรือเป็นข้อความธรรมดา ดังนั้นเมื่อฉันต้องการตรวจสอบแฮช ฉันเพียงแค่เพิ่ม 1234 เข้าไปในรหัสผ่านด้วยข้อความธรรมดาและเรียกใช้ฟังก์ชันการแฮชอีกครั้ง
in flag
เกลือจะถูกเก็บไว้ในข้อความธรรมดา ไม่ผ่านการแฮช มันถูกเข้ารหัสด้วยรูปแบบที่ออกแบบให้ง่ายสำหรับทุกคนในการย้อนกลับ คล้ายกับเช่น การเข้ารหัสเบส 64 เนื่องจากต้องเข้ารหัสไบนารีใด ๆ เพื่อบันทึกเป็นข้อความธรรมดา คุณสามารถดูรายละเอียดในกรณีของ bcrypt ได้ที่ https://en.wikipedia.org/wiki/Bcrypt#Description
Z3R0 avatar
jp flag
ขอบคุณจริงๆ

โพสต์คำตอบ

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