เหตุใดยาดมจึงทำให้การโจมตีด้วยพจนานุกรมเป็นไปไม่ได้


85

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

ฉันเข้าใจกระบวนการและนำไปใช้ด้วยตนเองในบางโครงการของฉัน

s =  random salt
storedPassword = sha1(password + s)

ในฐานข้อมูลที่คุณจัดเก็บ:

username | hashed_password | salt

การใช้เกลือทุกครั้งที่ฉันเห็นจะเพิ่มเกลือที่ส่วนท้ายของรหัสผ่านหรือจุดเริ่มต้น:

hashed_Password = sha1(s + password )
hashed_Password = sha1(password + s)

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

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

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

ให้ฉันยกตัวอย่างวิธีที่ฉันเสนอให้แฮ็กเกอร์แฮ็กฐานข้อมูลผู้ใช้ด้วยรายการรหัสผ่านและแฮช:

ข้อมูลจากฐานข้อมูลที่ถูกแฮ็กของเรา:

RawPassword (not stored)  |  Hashed   |     Salt
--------------------------------------------------------
letmein                       WEFLS...       WEFOJFOFO...

พจนานุกรมรหัสผ่านทั่วไป:

   Common Password
   --------------
   letmein
   12345
   ...

สำหรับระเบียนผู้ใช้แต่ละรายการให้วนซ้ำรหัสผ่านทั่วไปและแฮช:

for each user in hacked_DB

    salt = users_salt
    hashed_pw = users_hashed_password

    for each common_password

        testhash = sha1(common_password + salt)
        if testhash = hashed_pw then
           //Match!  Users password = common_password
           //Lets visit the webpage and login now.
        end if

    next

next

ฉันหวังว่านี่จะอธิบายประเด็นของฉันได้ดีขึ้นมาก

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

อัปเดตเกี่ยวกับ Cracking Theory

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

ไซต์นี้อ้างว่าสามารถคำนวณ 2,300,000,000 SHA1 แฮชต่อวินาทีโดยใช้ GPU (ในสถานการณ์จริงอาจจะช้าลง แต่สำหรับตอนนี้เราจะใช้รูปที่ยกมา)

(((95 ^ 4) / 2300000000) / 2) * 10000 = 177 วินาที

กำหนดอักขระ ASCII ที่พิมพ์ได้เต็มช่วง 95 ตัวโดยมีความยาวสูงสุด 4 อักขระหารด้วยอัตราการคำนวณ (ตัวแปร) หารด้วย 2 (สมมติว่าเวลาเฉลี่ยในการค้นหารหัสผ่านโดยเฉลี่ยจะต้องใช้การเรียงสับเปลี่ยน 50%) เป็นเวลา 10,000 ผู้ใช้จะใช้เวลา 177 วินาทีในการคำนวณรหัสผ่านของผู้ใช้ทั้งหมดที่มีความยาว <= 4

มาปรับกันเล็กน้อยเพื่อความสมจริง

(((36 ^ 7) / 1000000000) / 2) * 10000 = 2 วัน

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

สิ่งสำคัญคือต้องตระหนักว่านี่เป็นการโจมตีด้วยกำลังเดรัจฉานเชิงเส้นการคำนวณทั้งหมดเป็นอิสระจากกันจึงเป็นงานที่สมบูรณ์แบบสำหรับระบบต่างๆในการแก้ปัญหา (IE ง่ายต่อการตั้งค่าคอมพิวเตอร์ 2 เครื่องที่รันการโจมตีจากปลายที่แตกต่างกันซึ่งจะใช้เวลาในการประหารชีวิตเพียงครึ่งเดียว)

ในกรณีของการแฮชรหัสผ่านซ้ำ ๆ 1,000 ครั้งเพื่อให้งานนี้มีราคาแพงในการคำนวณมากขึ้น:

(((36 ^ 7) / 10000000000) / 2) * 1000 วินาที = 10.8839117 ชั่วโมง

นี้แสดงให้เห็นความยาวสูงสุด 7 ตัวอักษรตัวเลขที่น้อยกว่าครึ่งหนึ่งของการดำเนินการความเร็วจากตัวเลขที่ยกมาสำหรับผู้ใช้คนหนึ่ง

การแฮชซ้ำ 1,000 ครั้งบล็อกการโจมตีแบบครอบคลุมได้อย่างมีประสิทธิภาพ แต่การโจมตีแบบกำหนดเป้าหมายบนข้อมูลผู้ใช้ยังคงมีช่องโหว่


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

25
เนื่องจากแครกเกอร์ก็เหมือนทากและเกลือจะทำให้เมือกบนผิวหนังแห้งและฆ่ามันได้
TED

6
@TED: ฉันชอบแครกเกอร์เค็มมากกว่า ทากเค็มไม่มาก
FrustratedWithFormsDesigner

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

3
@ Tom Gullen - คุณมีภาพเพียงครึ่งเดียว หากไม่มีเกลือผู้โจมตีจะไม่ใช้วิธีที่คุณสาธิตใน "อัปเดต 2" เขาเพียงแค่ทำการค้นหาในตารางและรับรหัสผ่านใน O (1) หรือ O (log n) time (n คือจำนวนรหัสผ่านของผู้สมัคร) เกลือเป็นสิ่งที่ป้องกันสิ่งนั้นและบังคับให้เขาใช้วิธี O (n) ที่คุณแสดงให้เห็น อีกเทคนิคหนึ่ง (การเพิ่มความแข็งแกร่งของคีย์) อาจทำให้ความพยายามในลูปของคุณแต่ละครั้งใช้เวลาเต็มวินาทีซึ่งหมายความว่าจะใช้เวลา 3 ปีในการทดสอบเหล่านั้น ... และด้วยรหัสผ่านเพียง 10k คุณมีแนวโน้มที่จะถอดรหัสรหัสผ่านเป็นศูนย์ เวลา.
erickson

คำตอบ:


31

ใช่คุณต้องใช้เวลาเพียง 3 วันสำหรับ sha1 (เกลือ | รหัสผ่าน) นั่นเป็นเหตุผลที่อัลกอริทึมการจัดเก็บรหัสผ่านที่ดีใช้การแฮชการทำซ้ำ 1,000 ครั้ง: คุณจะต้องใช้เวลา 8 ปี


3
+1 ที่กระชับและตรงประเด็นที่สุดจนถึงตอนนี้ฉันไม่รู้ว่านี่เป็นตัวเลือก
Tom Gullen

เห็นได้ชัดว่าคุณไม่เคยทำมาตรฐานแฮชในระบบของคุณ คุณสามารถคำนวณ sha1 ได้หลายล้านครั้งต่อวินาที 1,000 รอบไม่มีความหมายสำหรับผู้โจมตี -1 เนื่องจาก sha1 เป็นฟังก์ชันแฮชที่เสีย
rook

เห็นได้ชัดว่าฉันใช้ชื่อและตัวเลขจากคำถาม ถ้าคุณเคยได้ยินเกี่ยวกับหัวข้อและความชัดเจน ... โอ้มันเป็น Rook ไม่เป็นไร.
ลุกโชน

1
@Rook 1,000 รอบหมายความว่าจะใช้เวลานานกว่า 1,000 เท่าในการบังคับเดรัจฉาน ดูเหมือนเป็นคุณสมบัติที่ดีสำหรับฉัน
Tom Gullen

ถ้าผู้โจมตีสามารถเดารหัสผ่านได้นี่เหมือนกันสำหรับการเข้าสู่ระบบ (หรือมีบางอย่างหลุดรอดมาหาฉัน lol)
khaled_webdev

62

มันไม่ได้หยุดการโจมตีพจนานุกรม

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

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

อัปเดต :

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

ฉันทราบข้อเท็จจริงว่ามีการเพิ่มการรองรับ SHA-256 และ SHA-512 ใน GNU crypt เวอร์ชันใหม่กว่า


17
+1 Salt ป้องกันไม่ให้รายการแฮชที่คำนวณล่วงหน้า (ตารางรุ้ง) เป็นประโยชน์ ผู้โจมตีต้องเริ่มต้นใหม่ทั้งหมด
Ian Boyd

2
ใน PHP คุณสามารถใช้ไลบรารี mcrypt หรือ bcrypt เพื่อการเข้ารหัสที่ดีกว่า md5 หรือ sha1 หากคุณติด md5 หรือ sha1 คุณควรจะ 'ยืด' โดยที่คุณแฮชรหัสผ่าน 1,000 ครั้งก่อนที่คุณจะมาถึงสิ่งที่เก็บไว้ในฐานข้อมูล ซึ่งจะทำให้เอนโทรปีเหมือนเดิม แต่จะเพิ่มเวลาในการคำนวณแฮช
Malfist

2
@ Tom Gullen คุณกำลังอ่านบทความอะไรอยู่? ผู้เชี่ยวชาญด้านตนเองหรือบทความที่ได้รับการตรวจสอบโดยเพื่อนในวารสารทางวิทยาศาสตร์?
Malfist

7
และเป็นนักพัฒนา Joe โดยเฉลี่ยของคุณที่สร้างบล็อก / โพสต์ความช่วยเหลือเกี่ยวกับวิธีการเขียนระบบ "ปลอดภัย" ความปลอดภัยไม่ใช่สิ่งที่คุณสามารถเลือกได้ แต่ต้องมีความรู้มากมาย มันไม่ยุติธรรม? อาจ. ปลอดภัยจริงหรือ? ในระดับปริญญา มีเหตุผลมีผู้เชี่ยวชาญด้านความปลอดภัย แต่แล้วอีกครั้งไม่ใช่ทุกอย่างจะต้องปลอดภัยเท่า Fort Knox นโยบายที่ดีที่สุดคือการใช้ระบบที่สร้างไว้ล่วงหน้าซึ่งออกแบบโดยผู้เชี่ยวชาญเหล่านั้นและปรับเปลี่ยนให้ตรงกับความต้องการของคุณ
Malfist

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

31

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

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

ตัวอย่าง: ด้วยเกลือ 64 บิต (เช่น 8 ไบต์) คุณต้องตรวจสอบรหัสผ่านเพิ่มเติม2 64ชุดในการโจมตีพจนานุกรมของคุณ ด้วยพจนานุกรมที่มี 200,000 คำคุณจะต้องทำ

200,000 * 2 64 = 3.69 * 10 24

การทดสอบในกรณีที่เลวร้ายที่สุด - แทนที่จะทดสอบ 200,000 ครั้งโดยไม่ใส่เกลือ

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

อัปเดต

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

อัปเดต 2

การอ่านที่ดีเกี่ยวกับการรักษาความปลอดภัยแฮชรหัสผ่านของคุณโดยทั่วไป (เกินกว่าคำถามเดิม แต่ก็ยังน่าสนใจ):

เพียงพอกับตารางสายรุ้ง: สิ่งที่คุณต้องรู้เกี่ยวกับรูปแบบรหัสผ่านที่ปลอดภัย

Corollary ของบทความ: ใช้แฮชเค็มที่สร้างด้วยbcrypt (อิงจาก Blowfish) หรือEksblowfishที่ช่วยให้คุณใช้เวลาตั้งค่าที่กำหนดได้เพื่อให้แฮชช้า


4
@ Tom Gullen - แม้จะมีนโยบายรหัสผ่านที่รัดกุมพอสมควรพจนานุกรมของผู้สมัครหลายร้อยล้านหรือสองสามพันล้านคนก็มีแนวโน้มที่จะได้รับความนิยมเนื่องจากรหัสผ่านทั้งหมดมีโอกาสไม่เท่ากัน (เนื่องจากผู้คนใช้ตัวช่วยจำมากกว่า RNG ในการเลือก) . พจนานุกรมขนาดนั้นสามารถคำนวณล่วงหน้าได้ในระบบสินค้าโภคภัณฑ์หากไม่ได้ใช้เกลือ หากมีการใช้เกลือผู้โจมตีจะต้องคำนวณแฮชใหม่ทุกครั้งและหากมีการทำแฮชซ้ำมากพออัตราการโจมตีของผู้โจมตีอาจช้าลงเหลือไม่กี่ครั้งต่อวินาที
erickson

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

2
@ 0xA3: อีกครั้ง: เป็นที่รู้จักของผู้โจมตีไม่ได้เป็นจุดของเกลือที่ เครื่องของคุณจำเป็นต้องเข้าถึงไม่ทางใดก็ทางหนึ่งดังนั้นผู้โจมตีที่บุกเข้าไปในเครื่องก็สามารถเข้าถึงได้ สถานการณ์ใด ๆ ที่ผู้โจมตีไม่ทราบว่าเกลือคือปลาเฮอริ่งแดง
Michael Borgwardt

1
ฉันคิดว่ามันคุ้มค่าที่จะกล่าวถึงว่าบทความที่เชื่อมโยงอธิบายตารางรุ้งผิด สิ่งที่เขาอธิบายคือแนบพจนานุกรมง่ายๆ ตารางสายรุ้งมีความแตกต่างกันมาก (และค่อนข้างซับซ้อนกว่า) มีคำอธิบายที่ดีงามของวิธีตารางรุ้งเป็นจริงการทำงานที่: kestas.kuliukas.com/RainbowTables
เจอร์รี่โลงศพ

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

17

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

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

เกลือที่ดีที่สุดจะถูกสุ่มเลือกจากเครื่องสร้างตัวเลขสุ่มแบบเข้ารหัส แปดไบต์เป็นขนาดที่ใช้งานได้จริงและมากกว่า 16 ไบต์ไม่มีจุดประสงค์ใด ๆ


เกลือทำมากกว่าแค่ "ทำให้งานของผู้โจมตีระคายเคืองมากขึ้น" มันกำจัดการโจมตีทั้งระดับ - การใช้พจนานุกรมที่มีการคำนวณล่วงหน้า

อีกองค์ประกอบหนึ่งที่จำเป็นในการรักษาความปลอดภัยรหัสผ่านอย่างสมบูรณ์และนั่นคือ "การเพิ่มความแข็งแกร่งให้กับคีย์" SHA-1 รอบเดียวไม่ดีพอ:อัลกอริธึมการแฮชรหัสผ่านที่ปลอดภัยควรจะคำนวณช้ามาก

หลายคนใช้ PBKDF2 ซึ่งเป็นฟังก์ชันที่ได้มาของคีย์ซึ่งจะดึงผลลัพธ์กลับไปยังฟังก์ชันแฮชหลายพันครั้ง อัลกอริทึม "bcrypt" คล้ายกันโดยใช้การได้มาของคีย์ซ้ำที่ช้า

เมื่อการดำเนินการแฮชช้ามากตารางที่มีการคำนวณล่วงหน้าจะเป็นที่ต้องการของผู้โจมตีมากขึ้นเรื่อย ๆ แต่เกลือที่เหมาะสมเอาชนะแนวทางนั้น


ความคิดเห็น

ด้านล่างนี้คือความคิดเห็นที่ฉันระบุไว้ในคำถาม


หากไม่มีเกลือผู้โจมตีจะไม่ใช้วิธีการที่แสดงใน "อัปเดต 2" เขาเพียงแค่ทำการค้นหาในตารางที่คำนวณล่วงหน้าและรับรหัสผ่านใน O (1) หรือ O (log n) time (n เป็นจำนวนรหัสผ่านของผู้สมัคร) เกลือคือสิ่งที่ป้องกันสิ่งนั้นและบังคับให้เขาใช้แนวทาง O (n) ที่แสดงใน "อัปเดต 2"

เมื่อลดการโจมตี O (n) แล้วเราต้องพิจารณาว่าแต่ละครั้งใช้เวลานานแค่ไหน การเพิ่มความแข็งแกร่งให้กับคีย์อาจทำให้ความพยายามแต่ละครั้งในลูปใช้เวลาเต็มวินาทีซึ่งหมายความว่าเวลาที่ต้องใช้ในการทดสอบรหัสผ่าน 10k กับผู้ใช้ 10k จะยืดจาก 3 วันเป็น 3 ปี …และด้วยรหัสผ่านเพียง 10k คุณก็มีแนวโน้มที่จะถอดรหัสเป็นศูนย์ รหัสผ่านในเวลานั้น

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

การเพิ่มความแข็งแกร่งของคีย์เป็นส่วนหนึ่งของอัลกอริธึมการสร้างคีย์มาตรฐาน PBKDF1 และ PBKDF2 จาก PKCS # 5 ซึ่งสร้างอัลกอริธึมการทำให้รหัสผ่านไม่ชัดเจน ("คีย์ที่ได้รับ" คือ "แฮช")

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


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

ด้วยรูปแบบการใช้รหัสผ่านการออกแบบที่ดีมันจะเป็นไปไม่ได้สำหรับผู้ชายคนนี้ที่จะกู้คืนรหัสผ่านใด ๆ


1
ฉันคิดว่าโดย "การโจมตีพจนานุกรม" ทอมหมายถึงการลองใช้รหัสผ่านที่คาดเดาได้ยาก (เช่นออกจากพจนานุกรมภาษามนุษย์โดยตรง) ไม่ใช่ตารางแฮช - ข้อความธรรมดาล่วงหน้า - นี่คือสิ่งที่ฉันนึกถึงเป็นครั้งแรกเมื่ออ่าน "พจนานุกรม" ใน บริบทนี้
Michael Borgwardt

@ Michael Borgwardt: ฉันเห็นด้วย @erickson หมายถึงการโจมตีพจนานุกรมที่คำนวณล่วงหน้า
Dirk Vollmar

1
Salt หยุดการโจมตีของพจนานุกรมที่คำนวณไว้ล่วงหน้า การเพิ่มความแข็งแกร่งของคีย์หยุดการโจมตีพจนานุกรม ต้องใช้ทั้งสองอย่างร่วมกันเพื่อการตรวจสอบรหัสผ่านที่ปลอดภัย
erickson

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

7

จุดประสงค์ของการเค็มคือการป้องกันการตัดจำหน่ายจากความพยายามของผู้โจมตี

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

ด้วยเกลือเฉพาะไซต์ผู้โจมตีจะต้องคำนวณตารางด้วยตัวเองจากนั้นจึงสามารถใช้กับผู้ใช้ทั้งหมดของไซต์ได้

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

แน่นอนว่าสิ่งนี้ไม่ได้ช่วยปกป้องรหัสผ่านที่อ่อนแอจริงๆได้โดยตรงจากพจนานุกรม แต่จะป้องกันรหัสผ่านที่รัดกุมพอสมควรจากการตัดจำหน่ายนี้


1
คำตอบที่สั้นและแม่นยำ - คุ้มค่าที่จะเพิ่มโดยไม่ต้องใส่เกลือหรือด้วยเกลือทั่วทั้งไซต์คุณสามารถระบุผู้ใช้ด้วยรหัสผ่านเดียวกันได้อย่างง่ายดายและจะต้องบังคับอย่างดุร้ายเท่านั้น ด้วยเกลือต่อผู้ใช้คุณไม่สามารถทำเช่นนั้นได้
snemarch

6

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

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

แก้ไข - เพิ่งสังเกตเห็นประเด็นหลักในความคิดเห็นด้านบน


1
คุณควรแก้ไขเพื่อระบุเกลือต่อผู้ใช้ ไซต์ที่ใช้ Salt ทั่วทั้งไซต์จะยังช่วยให้คุณตรวจพบรหัสผ่านที่เหมือนกันได้
snemarch

@snemarch - ใช่ - ขอบคุณมากสำหรับความแตกต่างที่สำคัญนี้!
Dominik Weber

5

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

สมมติว่าเรากำลังทำงานร่วมกับ SHA1 โดยใช้ประโยชน์จากการหาประโยชน์ล่าสุดที่ค้นพบด้วย algo นี้และสมมติว่าเรามีคอมพิวเตอร์ที่ทำงานด้วยความเร็ว 1,000,000 แฮช / วินาที จะต้องใช้เวลา 5.3 ล้านล้านล้านปีในการค้นหาการชนกันดังนั้นใช่ php สามารถทำงานได้ 300 วินาที woop ใหญ่ไม่สำคัญจริงๆ เหตุผลที่เราไม่สนใจก็เพราะถ้ามีใครไม่อยากสร้างวลีทั่วไปในพจนานุกรมทั้งหมด (2 ^ 160 คนยินดีต้อนรับสู่ยุค 2007)

นี่คือฐานข้อมูลจริงโดยมีผู้ใช้ 2 คนที่ฉันใช้เพื่อการทดสอบและเพื่อการดูแลระบบ

RegistrationTime        UserName        UserPass    
1280185359.365591       briang      a50b63e927b3aebfc20cd783e0fc5321b0e5e8b5
1281546174.065087       test        5872548f2abfef8cb729cac14bc979462798d023

ในความเป็นจริงรูปแบบการทำเกลือคือ sha1 ของคุณ (เวลาลงทะเบียน + ชื่อผู้ใช้) เอาเลยบอกรหัสผ่านนี่คือรหัสผ่านจริงในการผลิต คุณสามารถนั่งที่นั่นและแฮชรายการคำใน php ไปป่า.

ฉันไม่ได้บ้าฉันเพิ่งรู้ว่านี่ปลอดภัย เพื่อความสนุกสนานรหัสผ่านของการทดสอบคือtestเพื่อเห็นแก่ความสนุกสนานรหัสผ่านการทดสอบคือ sha1(sha1(1281546174.065087 + test) + test) = 5872548f2abfef8cb729cac14bc979462798d023

คุณจะต้องสร้างตารางรุ้งทั้ง perpended ด้วย27662aee8eee1cb5ab4917b09bdba31d091ab732สำหรับเพียงแค่ผู้ใช้นี้ นั่นหมายความว่าฉันสามารถอนุญาตให้รหัสผ่านของฉันไม่ให้ถูกบุกรุกได้ทั้งหมดโดยตารางสายรุ้งเดียวแฮกเกอร์จำเป็นต้องสร้างตารางสายรุ้งทั้งหมดสำหรับ 27662aee8eee1cb5ab4917b09bdba31d091ab732 เพื่อทดสอบและอีกครั้ง f3f7735311217529f2e020468004a2aa5b3dee7f สำหรับ briang ลองนึกย้อนไปถึง 5.3 ล้านล้านล้านปีสำหรับแฮชทั้งหมด ลองนึกถึงขนาดของการจัดเก็บแฮชเพียง 2 ^ 80 (ซึ่งมากกว่า 20 yottabytes ) มันจะไม่เกิดขึ้น

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


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

ใส่เงินของคุณที่ปากของคุณ?
ไม่ระบุตัวตน

แน่นอน แต่คุณเพิ่งบอกฉันว่ารหัสผ่านในตัวอย่างของคุณคืออะไรให้เกลือรหัสผ่านที่แฮชและวิธีรวมรหัสผ่าน salt + (ไม่เรียกซ้ำ) และตราบใดที่รหัสผ่าน <= 5 ตัวอักษรตัวพิมพ์เล็กและตัวเลขคละกัน (ไม่มีช่องว่าง / อักขระพิเศษ) ฉันจะแจ้งให้คุณทราบว่าในกล่องนี้มีอะไรบ้าง หากคุณต้องการให้ฉันใส่เงินตามที่คุณแนะนำโปรดแจ้งให้เราทราบแม้ว่าความคิดเห็นของฉันไม่กี่นาทีอาจเป็นการประเมินที่ต่ำเกินไป แต่ก็ใช่ภายในไม่กี่ชั่วโมง
Tom Gullen

1
อาจจะเป็นวินาทีจริงๆให้ดูที่golubev.com/hashgpu.htmซึ่งใช้ GPU ในการคำนวณตามที่ยกมา "2300M / s SHA1 hashes per second" ด้วยอักขระ ASCII 95 ตัวที่มีตั้งแต่ 1-6 ตัวอักษรเราสามารถถอดรหัสได้ใน <6 นาที หากเรามีเพียงตัวอักษรพิมพ์เล็กและตัวเลขคละกันความยาวสูงสุด 8 ตัวอักษร <25 นาที ด้วยฐานข้อมูลข้อมูลผู้ใช้ 10,000 รายการเราสามารถค้นหารหัสผ่าน ASCII แบบเต็มทั้ง 4 ตัวได้ในเวลา <200 วินาที ((((95 ^ 4) / 2300000000) / 2) * 10,000) (ค่าใช้จ่ายมากกว่าที่ยกมาและความเร็วของ GPU ที่ยกมาอาจเป็นสถานการณ์ที่ดีที่สุด)
Tom Gullen

ใช่การใส่เกลือไม่ได้ทำให้คุณไม่สามารถบังคับรหัสผ่านนั้นได้ ทำให้ยากขึ้นสำหรับคุณในการสร้าง ((10 ^ 5) * (94 ^ 10)) = 10 ^ 24 หากผู้ใช้มีรหัสผ่านประมาณ 10 อักขระซึ่งยากกว่า 10 ^ 19 ที่ไม่มีแฮชมาก อีกครั้งที่จะไม่ทำให้รหัสผ่านเดียวยากขึ้น แต่การทำลายรหัสผ่านทั้งหมดนั้นเป็นไปไม่ได้ด้วยตารางสายรุ้งที่ประมวลผลล่วงหน้า (และตรวจสอบคณิตศาสตร์ของฉันที่นี่ แต่ฉันเชื่อว่า 10 ^ 25/2300000000/60/60/24/365/1000 = 137869 ~ milinea สำหรับรหัสผ่านของทุกคน) หากเราต้องการรหัสผ่านที่รัดกุมขึ้นเราจะไม่ใส่รหัสผ่านเราใช้สิ่งต่างๆเช่นการแลกเปลี่ยนคีย์ Diffie - Hellman
ไม่ระบุตัวตน

3

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

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


ในสถานการณ์ของ OP ผู้โจมตีได้เกลือจากฐานข้อมูลและจะต้องลองเกลือทุกรายการใน "พจนานุกรม" ...ฉันคิด.
FrustratedWithFormsDesigner

2

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


2

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


1

เกลือทำให้โต๊ะสายรุ้งการโจมตีของยากขึ้นมากเนื่องจากทำให้แฮชรหัสผ่านเดียวยากขึ้นมาก ลองนึกภาพคุณมีรหัสผ่านที่น่าเกลียดน่ากลัวเพียงแค่หมายเลข 1 การโจมตีโต๊ะสายรุ้งจะทำลายสิ่งนี้ทันที

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

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


โปรดดูการอัปเดต # 2 คุณเพียงแค่มีรหัสผ่านดิบและคำนวณแฮชทั้งหมดเทียบกับเกลือสำหรับบันทึกผู้ใช้แต่ละรายการ
Tom Gullen

2
แน่นอนว่าทอมฉันเห็นด้วย แต่ประเด็นก็คือแฮ็กเกอร์ต้องทำกระบวนการที่ใช้เวลานานน่าเกลียดนั้นหนึ่งครั้งสำหรับ แต่ละรหัสผ่านหากมีการใช้เกลือ ดังนั้นเกลือจึงทำให้การใช้โต๊ะสายรุ้งยากขึ้น
Cory House

3
@ Tom Gullen: การสร้างตารางสายรุ้งที่มีเกลือเป็นไปได้ก็ต่อเมื่อมีการใช้เกลือทั่วทั้งไซต์ การล้างเกลือต่อผู้ใช้ทำให้การโจมตีโต๊ะสายรุ้งไร้ประโยชน์มาก
snemarch
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.