รหัสผ่านแฮช php.ini

ฉันมีระบบการเข้าสู่ระบบขั้นพื้นฐานที่ตรวจสอบสิทธิ์ผู้ใช้โดยใช้ตารางผู้ใช้ในฐานข้อมูล mysql ด้วย php

ใครช่วยอธิบายหน่อยว่ารหัสผ่านแฮชมีไว้เพื่ออะไร วิธีใช้ php และสิ่งที่เก็บไว้ในฐานข้อมูลจริงๆ

ขอบคุณ


person TechplexEngineer    schedule 24.08.2010    source แหล่งที่มา
comment
ดู stackoverflow.com/questions/3505346/php-md5-explained/   -  person Chris    schedule 25.08.2010
comment
เป็นไปได้ที่ซ้ำกันของ แฮชและเกลือที่ปลอดภัยสำหรับรหัสผ่าน PHP   -  person rook    schedule 25.08.2010


คำตอบ (4)


ใครสามารถอธิบายได้ว่าจุดของการแฮชรหัสผ่านคืออะไร

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

จะทำอย่างไรกับ php และสิ่งที่เก็บไว้ในฐานข้อมูลจริงๆ

หากต้องการใช้ใน PHP คุณเพียงใช้สตริงในตัวอย่างนี้ $password = 'password'; และใช้คำสั่ง sha1(); สิ่งนี้จะคืนค่าบางอย่างเช่น d0be2dc421be4fcd0172e5afceea3970e2f3d940 นอกจากนี้ แนวทางปฏิบัติที่ดีคือ 'เกลือ' รหัสผ่านด้วยสคริปต์ php ของคุณ เพื่อให้สคริปต์เข้าสู่ระบบสคริปต์ PHP จำเป็นในการเข้าสู่ระบบได้สำเร็จ ตัวอย่าง:

<?php
    $salt1 = '2348SDasdf!^*__';
    $salt2 = '_a35j@*#(lsdf_';
    $password = sha1($salt1.$_POST['password'].$salt2); // d0be2dc421be4fcd0172e5afceea3970e2f3d940
?>

จากนั้นใส่ $password ลงในฐานข้อมูลของคุณ เมื่อเข้าสู่ระบบ คุณจะต้องเติมรหัสผ่านที่กำหนดให้เรียกใช้ผ่าน sha1 เพื่อให้ตรงกับรหัสผ่านในฐานข้อมูล คุณแทรกลงในฐานข้อมูลเช่นเดียวกับสตริงอื่นๆ เพียงตรวจสอบให้แน่ใจว่าคุณมีความยาวเพียงพอสำหรับคอลัมน์ที่คุณพยายามแทรกด้วย

person Robert    schedule 24.08.2010
comment
นี่ไม่ใช่คำตอบที่ดีนัก เนื่องจากเกลือควรเป็นแบบสุ่ม หากการเกลือคงที่ การโจมตีแบบ bruteforce สามารถถอดรหัสรหัสผ่านพร้อมกันได้ (เช่น ต่อคำในพจนานุกรมที่สร้างขึ้น คุณจะคำนวณหนึ่งแฮชและดูว่าตรงกับผู้ใช้ N คนหรือไม่) แต่ถ้าคุณสุ่มเลือก จะต้องคำนวณแฮชสำหรับทุกคำ และ ผู้ใช้ทุกคน โดยบวกปัจจัย N เข้ากับความซับซ้อน - person mvds; 26.08.2010
comment
ตรงกันข้ามกับที่พวกเขารู้จักเกลือด้วยการหาฐานข้อมูล ทั้งสองวิธีต่างก็มีข้อบกพร่อง หากเป็นการสุ่ม คุณจะต้องเก็บเกลือไว้ที่ไหนสักแห่ง ซึ่งถ้าใครเข้าถึงเกลือนั้นได้ ก็จะเป็นการง่ายพอๆ กับการใช้กำลังดุร้าย - person Robert; 26.08.2010

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

ดังนั้นคุณจึงแฮชก่อนที่จะจัดเก็บ ดังนั้นคุณสามารถตรวจสอบได้ว่ารหัสผ่านนั้นใช้ได้หรือไม่ แต่ไม่สามารถอนุมานรหัสผ่านจากแฮชได้

เว้นแต่คุณจะใช้แฮชที่อ่อนแอ หากคุณเพียง sha1($password) คุณจะพบว่าการใส่แฮชของรหัสผ่านที่ใช้บ่อยลงใน Google จะให้รหัสผ่านภายในเวลาไม่ถึง 0.1 วินาที* (แต่ไม่เช่นนั้น คุณจะพบตารางสีรุ้งสำหรับแฮชทุกประเภท)

ดังนั้นคุณต้องการเพิ่ม "เกลือ" นั่นหมายความว่าคุณสร้างค่าขยะ:

$salt = rand().rand().rand();

แล้วเก็บ

$hash = $salt."-".sha1($salt.$password);

ในการตรวจสอบ คุณจะรู้เกลือและคุณสามารถตรวจสอบได้ว่ารหัสผ่านนั้นถูกต้องหรือไม่ แต่การรู้แฮชและเกลือทำให้การกู้คืนรหัสผ่านยังทำได้ยาก (เว้นแต่คุณจะมีโต๊ะสายรุ้งซึ่งมีเกลืออยู่ด้วย)

* สิ่งนี้ต้องการคำอธิบายบางอย่าง: ครั้งหนึ่งฉันเคยใช้ตารางผู้ใช้ขนาดใหญ่และพบว่ามีแฮชปรากฏขึ้นหลายครั้ง ฉันค้นหารายการที่เกิดขึ้นมากที่สุดใน Google และมันกลับเป็น computer

person mvds    schedule 24.08.2010
comment
MD5 ควรได้รับการพิจารณาว่าใช้งานไม่ได้ด้วยการเข้ารหัสและไม่เหมาะสมสำหรับการใช้งานต่อไป kb.cert.org/vuls/id/836068 - person webbiedave; 25.08.2010
comment
rand() ไม่ปลอดภัยด้วยการเข้ารหัส เกลือควรเป็นคอลัมน์แยกต่างหาก นั่นเป็นการออกแบบฐานข้อมูลที่ไม่ดี - person rook; 25.08.2010
comment
ดังนั้นหากแฮ็กเกอร์รู้ว่าเกลือคืออะไร นั่นจะไม่ทำลายจุดประสงค์ของการเกลือโดยสิ้นเชิงใช่หรือไม่ - person TechplexEngineer; 25.08.2010
comment
@The Rook: แม้ว่าฉันจะเห็นด้วย แต่มันก็ยังนอกประเด็นอยู่เล็กน้อย (และบอกตามตรง ฉันไม่เห็นด้วย เพราะฉันต้องการเก็บรหัสผ่าน salt+hash เป็นก้อนข้อมูลที่สวยงามและสวยงามไม่ว่าจะหยิบมันไปที่ไหนก็ตาม Salt และ hash นั้นไร้ค่าเมื่อแยกจากกัน ฉันจะแพ็ค/แกะพวกมันเมื่อจำเป็นเท่านั้น ส่วนที่เหลือของระบบก็เห็นมันเป็นสตริงเดียว) - person mvds; 25.08.2010
comment
@TechplexEngineer มันไม่ทำลายวัตถุประสงค์ คุณใส่รหัสผ่านของคุณเพื่อทำให้ยากขึ้น คุณล็อคประตูบ้านเพื่อป้องกันการโจรกรรมเล็กๆ น้อยๆ แต่โจรที่มุ่งมั่นจะไม่ถูกขัดขวางด้วยบางสิ่งเช่นประตูที่ถูกล็อค - person Robert; 25.08.2010
comment
@Techplex: ไม่ เพราะถ้าเขารู้ว่าเกลือคือ 7236817 เขาจะต้องย้อนกลับแฮชของ 7236817your_password อย่างมีประสิทธิภาพ ซึ่งจะมีโอกาสน้อยที่จะเกิดขึ้นบนตารางสายรุ้ง นอกจากนี้ การบังคับใช้อย่างดุเดือดกับบัญชีผู้ใช้ทั้งหมดของคุณจะทำให้ผู้โจมตีต้องแฮชรหัสผ่านทุกอันที่เขาพยายามทุกครั้งที่พบเกลือ ดังนั้นแค่ทำให้เกลือยาวและใส่มากกว่า 0-9 ลงไป! - person mvds; 25.08.2010
comment
@mvds ฉันเดาว่านั่นหมายความว่าเกลือของคุณเป็นตัวอักษรและตัวเลขหรืออาจเป็นเพียงฐาน 16 เกลือควรเป็น base256 (ไบต์เต็มต่ออักขระ) คุณต้องการให้อัตราส่วนเอนโทรปีต่อความยาวสตริงมากที่สุด - person rook; 25.08.2010
comment
@ ดีมากฉันจะเก็บมันไว้ด้วยตัวอักษรและตัวเลข (หรือ OP จะกลับมาในภายหลังพร้อมกับปัญหาข้อมูลไบนารี mysql) แต่อย่างไรก็ตามตัวอย่างที่มี rand() นั้นง่ายที่สุดในการรับข้อความ - person mvds; 25.08.2010

แฮชคือ "ฟังก์ชันทางเดียว" คุณป้อนรหัสผ่านและได้รับเอาต์พุตเฉพาะโดยประมาณที่ไม่สามารถแปลงกลับเป็นรหัสผ่านจริงได้ (ตามความเป็นไปได้ในการคำนวณ) มันจะดูแตกต่างออกไปขึ้นอยู่กับแฮช ตัวอย่างเช่น ด้วย sha1 (http://php.net/manual/en/function.sha1.php) คุณจะได้สตริงที่ยาว 20 ไบต์เสมอ

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

person Jonathan    schedule 24.08.2010
comment
คุณสามารถค้นหารายการรหัสผ่านทั่วไปจำนวนมากได้อย่างง่ายดาย การเขียนโปรแกรมเพื่อคำนวณแฮชของแฮชทั้งหมดนั้นเป็นเรื่องเล็กน้อย แล้วเปรียบเทียบแฮชเหล่านั้นกับฐานข้อมูลรหัสผ่าน แน่นอนว่านี่จะเกี่ยวข้องก็ต่อเมื่อมีคนเข้าถึงรหัสผ่านที่แฮชแล้วเท่านั้น นอกจากนี้ยังสามารถป้องกันได้อย่างมีประสิทธิภาพโดยใช้เกลือตามที่กล่าวไว้ในโพสต์อื่น - person Jonathan; 25.08.2010
comment
ใช่ ถ้าฉันบอกคุณว่าฉันแฮชรหัสผ่านโดยใช้ md5($password) และแฮชของฉันคือ 08b5411f848a2581a41672a759c87380 คุณช่วยบอกฉันได้ไหมว่ารหัสผ่านของฉันคืออะไร - person mvds; 25.08.2010
comment
@โจนาธาน: คุณไม่จำเป็นต้องทำสิ่งเหล่านี้ด้วยตัวเองอีกต่อไป สิ่งเหล่านี้มีอยู่และจัดทำดัชนีฟรี - person mvds; 25.08.2010
comment
แฮชนั้นส่งคืนผลลัพธ์ที่ไม่คาดคิด: ตารางผู้ใช้! - person mvds; 25.08.2010
comment
ถูกต้อง แต่คุณไม่จำเป็นต้องใช้ md5decryption.com Google ก็ทำได้ดี - person mvds; 25.08.2010

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

person James    schedule 24.08.2010
comment
นี่ไม่ใช่ประเด็น ดังนั้น ประเด็นก็คือ หากฐานข้อมูล ของคุณ ถูกขโมย คุณ ต้องบอกผู้ใช้ 1 ล้านคนของคุณว่ารหัสผ่านของพวกเขาถูกขโมย และพวกเขาจะต้องเปลี่ยนรหัสผ่าน พวกเขาจะไม่ทำ ดังนั้นอาจมีคนวิกลจริตที่สามารถเข้าถึงบัญชีของผู้ใช้ 900,000 คนในระบบของคุณ ดังนั้นคุณจึงมีปัญหาที่ใหญ่ที่สุด - person mvds; 25.08.2010
comment
เป็นจุดดี @mvds ยกเว้นว่าคุณสามารถบังคับให้ผู้ใช้ของคุณเปลี่ยนรหัสผ่านเพื่อแก้ไขปัญหานั้น - มันจะไม่ทำให้คุณโด่งดัง แต่จะได้ผล แต่ของฉันยังคงเป็นจุดที่ดี แน่นอนว่า หากแฮกเกอร์แฮ็กเว็บไซต์ของผู้อื่นโดยใช้รหัสผ่านที่ขโมยมาจากของคุณ นั่นไม่ใช่ปัญหาของคุณจริงๆ แต่คุณคิดว่าลูกค้าของคุณ (อาจเป็นอดีต) จะเห็นมันด้วยวิธีนั้นหรือไม่ - person James; 25.08.2010
comment
แน่นอนว่ามันขึ้นอยู่กับ หากคุณเป็นบริษัท คุณสามารถบังคับพนักงานของคุณให้เปลี่ยนรหัสผ่านได้ 100% และพวกเขาจะไม่ออกจากบริษัทเพราะเรื่องนั้นจริงๆ หากคุณเป็น Gmail/Hotmail คุณสามารถบังคับได้ประมาณ 80% (สมมติว่ามีบัญชีเสียจำนวนมาก) และลูกค้าบางรายจะทิ้งคุณไป หากคุณอยู่ในขอบเขตของสิ่งที่สำคัญน้อยกว่า (โซเชียลเน็ตเวิร์ก เกม ฟอรัม ...) คุณน่าจะทำให้ผู้ใช้ที่หามาได้ยากถึง 50% เนื่องจากคุณจะต้องบล็อกบัญชี ณ จุดใดจุดหนึ่ง หาก ผู้ใช้ไม่ตอบสนองต่อคำขอของคุณ นอกจากนี้ยังมีปัญหาว่าในกรณีสุดท้ายคุณ--ต่อ - person mvds; 26.08.2010
comment
-- อาจไม่มีกลไกที่เหมาะสมในการตรวจสอบสิทธิ์ผู้ใช้จริงๆ (คำถามลับ วันเกิดจริง ...) ดังนั้นความเสี่ยงที่แท้จริงคือคุณจะเลิกกิจการ ไม่ใช่แค่เพราะสื่อไม่ดีเท่านั้น - person mvds; 26.08.2010