วิธีที่ดีที่สุดในการจัดเก็บรหัสผ่านในฐานข้อมูล [ปิด]


475

ฉันกำลังทำงานในโครงการที่ต้องมีการรับรองความถูกต้อง (ชื่อผู้ใช้และรหัสผ่าน)

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

ฉันใช้ C # และเชื่อมต่อกับเซิร์ฟเวอร์ Express 2008 ใครสามารถแนะนำ (ด้วยตัวอย่างให้ได้มากที่สุด) วิธีที่ดีที่สุดในการจัดเก็บข้อมูลประเภทนี้คืออะไร?

ป.ล. ฉันเปิดรับความคิดที่ว่าข้อมูลนี้ไม่ถูกเก็บไว้ในฐานข้อมูลหากสามารถให้เหตุผลที่ดีได้


1
ไม่ว่าคุณจะทำอะไรถ้าคุณไปด้วยการเข้ารหัสอย่าเก็บรหัสไว้ในรหัสตามที่ผู้โพสต์ก่อนหน้าพูดถึง นั่นเป็นเพียงการปฏิบัติที่ไม่ดี
วู้ดดี้

12
'วิธีทำรหัสผ่านถูกต้องหรือไม่' เป็นคำถามที่สำคัญ มันเป็นปัญหาที่ยากและมีข้อผิดพลาดที่มีผลกระทบร้ายแรง (จำสิ่งที่เกิดขึ้นกับเทสโก้และ LinkedIn) ฉันคิดว่าคำถามนี้ควรเปิดใหม่ที่programmers.stackexchange.com
Colonel Panic

2
ดีกว่าที่จะยึดตามมาตรฐาน - ดูen.wikipedia.org/wiki/PBKDF2คุณต้องค้นหาการนำไปใช้ในภาษาของคุณเท่านั้น
Boris Treukhov

5
คำถามนี้มีคำตอบอย่างกว้างขวางในฟอรัมความปลอดภัย
gioele

คำตอบ:


405

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

ดังนั้นในขณะที่มันเป็นสิ่งที่ดีที่คุณคิดเกี่ยวกับเรื่องนี้และเป็นคำถามที่ดีนี่เป็นคำถามที่ซ้ำกันจริง ๆ (อย่างน้อย):

เพื่อชี้แจงเพิ่มเติมเล็กน้อยเกี่ยวกับ salting bit อันตรายด้วยการเพียงแค่ใส่รหัสผ่านและการจัดเก็บนั่นคือถ้าผู้บุกรุกบุกรุกฐานข้อมูลของคุณพวกเขายังสามารถใช้สิ่งที่รู้จักกันในชื่อRainbow tableเพื่อ "ถอดรหัส" รหัสผ่าน (อย่างน้อยผู้ที่แสดงในตารางสายรุ้ง) ในการหลีกเลี่ยงปัญหานี้ผู้พัฒนาเพิ่มเกลือลงในรหัสผ่านซึ่งเมื่อทำอย่างถูกต้องแล้วจะทำให้การโจมตีแบบสายรุ้งเป็นไปไม่ได้ที่จะทำ โปรดทราบว่าการเข้าใจผิดที่พบบ่อยคือการเพิ่มสตริงที่ไม่ซ้ำและยาวแบบเดียวกันให้กับรหัสผ่านทั้งหมด ในขณะที่สิ่งนี้ไม่น่ากลัวแต่เป็นการดีที่สุดที่จะเพิ่มเกลือที่ไม่ซ้ำกันในทุกรหัสผ่าน อ่านเพิ่มเติม


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

14
ไม่เพียง แต่เป็นว่าสิ่งที่ผมพูดว่าผมกำกับเขาไปมากมายเหลือเฟือของโพสต์ที่หารือเกี่ยวกับเกลือและเช่นเพิ่มเติมที่ ...
Paolo Bergantino

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

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

40
@ Robert: ที่ได้รับอันตรายใกล้เคียงกับความหมายเกมเล็ก ๆ น้อย ๆ แต่ฉันจะแก้ไขได้กระนั้น ...
Paolo Bergantino

54

พื้นหลัง คุณไม่เคย ... จริง ๆ ... จำเป็นต้องรู้รหัสผ่านของผู้ใช้ คุณเพียงแค่ต้องการตรวจสอบผู้ใช้ที่เข้ามารู้รหัสผ่านสำหรับบัญชี

Hash It: เก็บรหัสผ่านของผู้ใช้ที่แฮช (การเข้ารหัสแบบทางเดียว) ผ่านฟังก์ชั่นแฮชที่แข็งแกร่ง การค้นหา "c # เข้ารหัสรหัสผ่าน" ให้ตัวอย่างมากมาย

ดูผู้สร้างแฮช SHA1 ออนไลน์เพื่อดูแนวคิดเกี่ยวกับฟังก์ชันแฮชที่สร้าง (แต่อย่าใช้ SHA1 เป็นฟังก์ชันแฮชใช้อะไรที่แรงกว่าเช่น SHA256)

ตอนนี้รหัสผ่านที่ถูกแฮชหมายความว่าคุณ (และขโมยฐานข้อมูล) ไม่สามารถย้อนกลับการแฮชกลับไปเป็นรหัสผ่านเดิมได้

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

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

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

สินเชื่อพิเศษ:

คำถาม:ถ้าฉันมีฐานข้อมูลของคุณฉันไม่สามารถใช้แคร็กเกอร์อย่าง John the Ripper และเริ่มแฮชได้จนกว่าฉันจะหาคู่ที่ตรงกับที่คุณเก็บไว้และรหัสผ่านที่แฮช (เนื่องจากผู้ใช้เลือกคำศัพท์สั้น ๆ อยู่ดี ... มันควรจะง่าย)

คำตอบ:ใช่ ... ใช่พวกเขาทำได้

ดังนั้นคุณควร 'เกลือ' รหัสผ่านของคุณ ดูบทความ Wikipedia เกี่ยวกับเกลือ

ดู"วิธีแฮชข้อมูลด้วยเกลือ" ตัวอย่าง C #


14
โพสต์ที่ดียกเว้นสิ่งหนึ่ง: md5 และ sha1 ถูกทำลาย คุณน่าจะไปด้วยอัลกอริธึมที่แรงกว่าเช่นตระกูล SHA2
เปาโล Bergantino

3
ขอบคุณเปาโล - คุณพูดถูก เนื่องจากการใช้ SHA2 นั้นง่ายเหมือนการใช้ MD5 & SHA1 โปรดใช้อัลกอริทึมแฮชที่แข็งแกร่งขึ้น
joej

5
SHA-1 ยังไม่พัง แต่การถอดความ Bruce Schneier: เดินอย่าวิ่งไปที่ SHA-2
เอียนบอยด์

2
"ดังนั้นคุณควร 'เกลือ' รหัสผ่านของคุณ" ... แต่โดยปกติเกลือนั้นจะถูกเก็บไว้ในฐานข้อมูลพร้อมกับรหัสผ่านดังนั้นสิ่งนี้จะช่วยได้อย่างไร ผู้โจมตี Te ต้องเพิ่มเกลือลงไปในวลีการโจมตีพจนานุกรมที่เขากำลังทดสอบ ความปลอดภัยนั้นจะมีความปลอดภัยมากกว่านั้นอย่างไรจะไม่เปิดเผยรหัสผ่านซ้ำ
trusktr

4
@ Joej "คุณไม่เคย ... จริง ๆ ... จำเป็นต้องรู้รหัสผ่านของผู้ใช้" - เป็นข้อสันนิษฐานที่สั้นมาก มีแอปพลิเคชั่นหลายประเภทที่มีการจัดเก็บรหัสผ่านในลักษณะที่สามารถเรียกคืนได้เป็นสิ่งที่จำเป็นอย่างแท้จริง ตัวอย่างเช่นแอปพลิเคชันที่ต้องลงชื่อเข้าใช้ระบบอื่นด้วยข้อมูลประจำตัวที่เก็บไว้ซึ่งจัดทำและอัปเดตโดยผู้ใช้เป็นประจำ
Francisco Zarabozo

29

ในฐานะที่เป็นกัญชาเค็มที่มีความแข็งหลักโดยใช้อัลกอริทึมที่ปลอดภัยเช่น sha-512


6
ในความคิดของฉันคุณควรใช้อัลกอริทึมช้า (เช่น Blowfish เป็นต้น) เพื่อเก็บรหัสผ่าน เขียนขึ้นนี้เป็นคำตอบที่ดีมาก: security.stackexchange.com/questions/211/... เพียงวางไว้ที่นี่เพราะหน้านี้ยังคงปรากฏในผลการค้นหาสูง
Dynom

2
การปฏิบัติตามคำแนะนำสำหรับการจัดเก็บรหัสผ่านนี้จะทำผิดอย่างมาก
mlissner

27

แนวทางปฏิบัติด้านความปลอดภัยที่ดีที่สุดคือไม่ต้องเก็บรหัสผ่านเลย (ไม่เข้ารหัสแม้แต่) แต่เพื่อเก็บแฮชเค็ม (ด้วยเกลือที่ไม่ซ้ำกันต่อรหัสผ่าน) ของรหัสผ่านที่เข้ารหัส

วิธีนี้เป็นไปไม่ได้เลยที่จะดึงรหัสผ่านแบบธรรมดา


11
เวย์นโดยการเติมเกลือก่อนคำนวณกัญชาตารางสายรุ้งจะพ่ายแพ้อย่างมีประสิทธิภาพหากเกลือมีขนาดเพียงพอ
Mike Rosenblum

11
@ Wayne Hartman: ไม่เช่นนั้น หากค่าเกลือถูกเปิดเผยคุณจะต้องสร้างตารางรุ้งใหม่สำหรับค่าเกลือเฉพาะนั้น จุดของตารางสายรุ้งคือการคำนวณค่าแฮชล่วงหน้า และไม่มีใครจะมีโต๊ะรุ้งสำหรับเกลือเฉพาะของเขา
เอียนบอยด์

10

ฉันอย่างละเอียดขอแนะนำให้อ่านบทความตารางเพียงพอกับ The Rainbow: สิ่งที่คุณต้องรู้เกี่ยวกับการรักษาความปลอดภัยรหัสผ่านแบบแผน [ลิงค์ตายคัดลอกที่อินเทอร์เน็ต Archive ] และวิธีการอย่างปลอดภัยเก็บรหัสผ่าน

ตัวเข้ารหัสจำนวนมากรวมอยู่ด้วยตัวเองคิดว่าพวกเขาเข้าใจความปลอดภัยและการแฮช น่าเศร้าที่พวกเราส่วนใหญ่ไม่ได้ทำ


1
@Janan ดูเหมือนว่าลิงค์จะเสียซึ่งเป็นความอัปยศ นี่คือทางเลือกcodahale.com/how-to-safely-store-a-password
zebrabox

6

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

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

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

RPXมอบวิธีที่ง่ายในการรวมการสนับสนุน OpenID เข้ากับแอปพลิเคชัน


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

3

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

ทุกอย่างถูกสร้างขึ้นเพื่อจุดประสงค์นี้ลองดูการเป็นสมาชิก asp.net


1

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


2
ฉันจะไม่ใช้ MD5 สำหรับการแปลงแป้นพิมพ์ - โดยทั่วไปแล้วmscs.dal.ca/~selinger/md5collision
zebrabox

3
ที่จริงแล้วมันไม่ได้หัก สิ่งที่พวกเขาสามารถทำได้คือค้นหาค่าแฮชเดียวกันสำหรับไฟล์สองไฟล์ที่แตกต่างกัน สิ่งที่พวกเขาไม่สามารถทำได้คือย้อนกลับ MD5 และรับรหัสผ่านที่ใช้งานได้
waiwai933

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

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