มีเหตุผลใดบ้างที่จะไม่ใช้ bcrypt กับที่อยู่อีเมล?

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

$email_hash = password_hash($email, PASSWORD_DEFAULT);

ฉันรู้ว่ามันมีไว้สำหรับรหัสผ่าน แต่อะไรล่ะ? ควรทำงานกับอีเมลด้วย... หากใช้อีเมลในการเข้าสู่ระบบ ไม่ควรแฮช/ใส่เกลือเหมือนกับรหัสผ่านใช่ไหม ฉันรู้ว่านี่ไม่ใช่วิธีปฏิบัติมาตรฐาน แต่ไม่เคยเข้าใจว่าทำไม

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


person Saul Tigh    schedule 21.04.2016    source แหล่งที่มา
comment
ไม่มีเหตุผลอะไรที่จะไม่ทำ ประหยัดค่าใช้จ่าย หากมีคนแฮ็กฐานข้อมูลของคุณ พวกเขาจะไม่สามารถเอาที่อยู่อีเมลออกไปได้ - คุณก็เช่นกัน ดังนั้น หากคุณต้องการที่อยู่อีเมลของผู้ใช้เพื่อวัตถุประสงค์อื่น คุณจะต้องถูกปกปิด   -  person Jay Blanchard    schedule 21.04.2016
comment
อีเมลถูกใช้เพื่อการสื่อสาร หากคุณแฮชที่อยู่อีเมลของผู้ใช้ทั้งหมด คุณจะสามารถติดต่อพวกเขาด้วยข่าวสารของเว็บไซต์/การอัปเดต/การรีเซ็ตรหัสผ่าน ฯลฯ ได้อย่างไร ไม่จำเป็นต้องมัน หากคุณกังวลว่าฐานข้อมูลของคุณจะถูกขโมย เพียงตรวจสอบให้แน่ใจว่าคุณได้อัปเดตซอฟต์แวร์ให้ทันสมัยอยู่เสมอ และใช้มาตรการรักษาความปลอดภัยอื่นๆ มากมายเพื่อป้องกันไม่ให้สิ่งนั้นเกิดขึ้น   -  person mferly    schedule 22.04.2016
comment
คุณต้องมีชื่อผู้ใช้ (ที่อยู่อีเมล) เพื่อที่จะสามารถเข้าสู่ระบบได้ หากคุณแฮชชื่อผู้ใช้โดยใช้ password_hash คุณจะได้รับค่าที่แตกต่างกันในแต่ละครั้ง ดังนั้นวิธีเดียวที่จะค้นหาบันทึกผู้ใช้คือลองแต่ละรายการ แฮชและดูว่าตรงกันหรือไม่   -  person Arjan    schedule 22.04.2016
comment
เหตุผลที่ @Arjan ระบุเป็นเหตุผลที่ดีที่สุดที่จะไม่ทำ   -  person Scott Arciszewski    schedule 22.04.2016
comment
@Arjan วิธีแก้ปัญหาที่ชัดเจนก็คือการใช้ password_verify() สำหรับที่อยู่อีเมลด้วย   -  person Jay Blanchard    schedule 22.04.2016


คำตอบ (1)


คุณต้องมีที่อยู่อีเมลเพื่อค้นหาบันทึกผู้ใช้

โดยปกติแล้วคุณจะทำสิ่งนี้:

function create_account(email, password) {
    var pwhash = password_hash($password, PASSWORD_BCRYPT);
    // insert into users values ($email, $pwhash);
}

function login(email, password) {
    // select pwhash from users where email = $email;
    return password_verify($password, $pwhash); // true or false
}

password_hash($email) จะส่งคืนค่าที่แตกต่างออกไปเสมอ เนื่องจาก bcrypt มีเกลืออยู่ในแฮช

จาก วิกิพีเดีย:

ตัวอย่างเช่น [bcrypt hash] $2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy ระบุพารามิเตอร์ต้นทุนเป็น 10 ซึ่งบ่งชี้ถึง 210 รอบการขยายคีย์ เกลือคือ N9qo8uLOickgx2ZMRZoMye และแฮชที่ได้คือ IjZAgcfl7p92ldGxad68LJZdL17lhWy

หรือจาก เอกสาร PHP:

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

person Jonathan    schedule 21.04.2016
comment
โดยสรุป นี่เป็นคำถาม PHP และคุณให้คำตอบ Node.js :) - person Scott Arciszewski; 22.04.2016
comment
ฉันคิดว่าฉันได้ปรับแต่งโค้ดเทียมนี้อย่างถูกต้องแล้ว - person Jonathan; 22.04.2016
comment
แต่คุณสามารถใช้ password_verify($email, $emailHash) สำหรับอีเมลได้เช่นกันใช่ไหม - person Jay Blanchard; 22.04.2016
comment
คุณสามารถทำได้ แต่คุณจะต้องวนซ้ำผู้ใช้ทั้งหมดในฐานข้อมูลเพื่อทำเช่นนั้น เพราะคุณไม่มีทางรู้ได้เลยว่า $emailHash ใดที่จะใช้ - person Jonathan; 22.04.2016