ภูมิปัญญาทั่วไป
ในฐานะที่เป็นเกร็ดความรู้ทั่วไป การรวมการเข้ารหัสแบบดั้งเดิมนั้นไม่ค่อยจะได้ชัยชนะโดยตรง มันสามารถเสริมคุณสมบัติบางอย่างหากทำถูกต้อง แต่ทำให้คุณสมบัติอื่นอ่อนแอลงดังนั้นควรทำเฉพาะเมื่อเสริมความแข็งแกร่งให้กับคุณสมบัติที่คุณสนใจและไม่ทำให้คุณสมบัติที่คุณสนใจลดลง
การรวม H และ F เป็นวิธีปฏิบัติทั่วไปที่จะรักษาความปลอดภัยเมื่อหนึ่งในนั้นกลายเป็นไม่ปลอดภัย แต่มีความคิดเห็นที่หลากหลายเมื่อพูดถึงว่าการผสมดังกล่าวปลอดภัยเท่ากับ MAX(H, F) หรือ MIN(H, F) ในแง่ของ ความปลอดภัยแทบไม่มีใครแนะนำว่าความปลอดภัยจะสูงหรือต่ำกว่านี้
คุณพบความคิดเห็นที่หลากหลายเพราะมันขึ้นอยู่กับว่าคุณทำการผสมผสานอย่างไร (นั่นหรือเพราะคนไม่รู้มันเลยเกิดขึ้น)
ฉันยังมีความคิดส่วนตัวเกี่ยวกับเรื่องนี้ ซึ่งมาจากวิชาคณิตศาสตร์ในโรงเรียน ดูเหมือนว่าจะชัดเจนสำหรับฉันว่าถ้า f:A -> B
และอย่างมาก |ก| > |ข|
และ g:B -> C
และอย่างมาก |ข| > |ค|
แล้ว ก(ฉ(x))
ควรมีการชนกันมากกว่า f หรือ g มาก
การนับการชนนั้นไม่เกี่ยวข้อง สิ่งที่สำคัญคือความยากลำบากในการค้นหาพวกเขา MD5(x)||SHA1(x)
เป็นแฮช 288 บิต และอาจมีการชนกันของสตริง 257 บิตน้อยกว่า SHA256(x)
â ในความเป็นจริงเป็นไปได้ว่า MD5(x)||SHA1(x)
ไม่มีการชนกันบนสตริง 257 บิตเลย ในขณะที่ SHA256(x)
จะต้องมีการชนกันตามหลักนกพิราบ แต่เรารู้วิธีค้นหาการชนกัน MD5(x)||SHA1(x)
สำหรับสตริงที่ยาวขึ้นเล็กน้อยในเวลาที่ยาวนานแต่ทำได้ (แพงกว่าการชนกันของ SHA1 เพียงเล็กน้อยเท่านั้น) ในขณะที่เราไม่รู้วิธีค้นหาการชนกันของ SHA256 เลย
แต่ความจริงที่ว่าเรารวมสองฟังก์ชันที่ซับซ้อนเข้าด้วยกันควรจะ "แตก" ได้ยากขึ้น
ไม่ นี่ไม่ใช่ข้อเท็จจริง ทั้งหมดขึ้นอยู่กับสิ่งที่คุณกำลังรวมและอย่างไร
เขียนสองแฮช
เกี่ยวกับ กัญชา และ ความต้านทานการชน, การเขียนสองแฮชจะลดความปลอดภัย. กล่าวอีกนัยหนึ่ง $H \circ F$ มีความทนทานต่อการชนน้อยกว่า $H$ หรือ $F$ ด้วยตัวมันเอง
มันง่ายที่จะเห็นว่าถ้า $F$ มีการปะทะกันแล้ว $H \circ F$: ถ้า $F(x_1 = F(x_2)$ กับ $x_1 \n x_2$ แล้ว $(H \circ F)(x_1) = H(F(x_1)) = H(F(x_2)) = (H \circ F)(x_2)$. สิ่งนี้เพียงอย่างเดียวหมายความว่าการเขียนสองแฮชนั้นไร้ประโยชน์หากสิ่งที่คุณสนใจคือการต้านทานการชนกัน: คุณอาจใช้ $F$.
ความต้านทานการชนของ $H \circ F$ ได้ดีกว่าของ $H$ ตามลำพัง. ถ้า $H$ มีการชนกัน $H(y_1) = H(y_2)$ กับ $y_1 \ไม่มี y_2$เพื่อใช้ข้อเท็จจริงนี้เพื่อหาข้อขัดแย้งสำหรับ $H \circ F$คุณต้องหาภาพล่วงหน้าสำหรับทั้งคู่ $y_1$ และ $y_2$. คุณจึงมั่นใจได้ว่า $F$ ทนต่อการชนและป้องกันพรีอิมเมจ $H \circ F$ ได้อย่างปลอดภัยกว่า $H$ ในแง่ของการต้านทานการชน อย่างไรก็ตาม เนื่องจากไม่ปลอดภัยกว่า $F$เหตุผลเดียวที่จะใช้การก่อสร้างนี้คือหากปรับปรุงคุณสมบัติอื่น ๆ
ถ้า $H \circ F$ มีการชนกันเช่นถ้า $H(F(x_1)) = H(F(x_2))$ กับ $x_1 \n x_2$แล้วอย่างใดอย่างหนึ่ง $F(x_1) = F(x_2)$ และนี่คือการปะทะกันของ $F$, หรือ $F(x_1) \ne F(x_2)$ และนี่คือการปะทะกันของ $H$. ดังนั้นการจัดองค์ประกอบภาพจึงไม่แย่ไปกว่าการต้านทานการชนของทั้งสองแบบ
การสร้างสองแฮชสามารถปรับปรุงความต้านทานของพรีอิมเมจได้ เพื่อใช้ประโยชน์จากโครงสร้างของ $H \circ F$ เมื่อต้องการค้นหาภาพล่วงหน้า คุณต้องค้นหาภาพล่วงหน้าทั้งสองแบบ $H$ แล้วเป็นภาพล่วงหน้าของสิ่งนั้น $F$. อย่างไรก็ตาม ไม่มีฟังก์ชันแฮชการเข้ารหัสใดที่ฉันจะถือว่ามีคุณสมบัติเป็นกระแสหลักที่เคยมีความต้านทานของพรีอิมเมจเสีย ดังนั้นจึงไม่ใช่เรื่องที่ต้องกังวลในทางปฏิบัติ
ความต้านทานต่อพรีอิมเมจเป็นปัญหาสำหรับ รหัสผ่าน ฟังก์ชันแฮช แต่ ฟังก์ชันแฮชรหัสผ่านเป็นรูปแบบดั้งเดิมของการเข้ารหัสที่แตกต่างอย่างสิ้นเชิงจากฟังก์ชันแฮชแบบธรรมดา. มีพารามิเตอร์ที่แตกต่างกันและวัตถุประสงค์ด้านความปลอดภัยที่แตกต่างกัน ความต้านทานการชนไม่เกี่ยวข้องกับการแฮชรหัสผ่าน การเขียนฟังก์ชันแฮชรหัสผ่านสองฟังก์ชันอาจสมเหตุสมผล แต่คุณต้องระวัง: เป็นไปได้ที่จะทำผิดอย่างแน่นอน.
การสร้างแฮชสองตัวยังสามารถปรับปรุงคุณสมบัติความปลอดภัยอื่นนอกเหนือจากคุณสมบัติที่กำหนดฟังก์ชันแฮชการเข้ารหัส แฮชมักใช้เป็น ออราเคิลแบบสุ่มและแฮชที่ใช้กันทั่วไป (เช่น ตระกูล SHA-2) เป็นที่ทราบกันดีว่าไม่สมบูรณ์ในฐานะออราเคิลแบบสุ่ม เนื่องจาก การโจมตีส่วนขยายความยาว. การสร้างแฮชสองตัว แม้แต่ฟังก์ชันเดียวกัน เช่นใน SHA256d(x) = SHA256(SHA256(x))
กำจัดการโจมตีแบบขยายความยาวและไม่แนะนำจุดอ่อนอื่นที่รู้จักในตัวเอง (âด้วยตัวของมันเองâ เป็นสิ่งสำคัญ: หากคุณผสม SHA256d และ SHA256 ในข้อมูลเดียวกัน ผลลัพธ์ที่ได้อาจเสียหายได้)
เชื่อมต่อสองแฮช
อีกวิธีง่ายๆ ในการรวมสองแฮชคือการต่อเข้าด้วยกัน: $H(x) || F(x)$. นี่คือการปรับปรุงที่ชัดเจนในแง่ของความต้านทานการชน: หากมีการชนสำหรับ $H || เอฟ$ก็ยังเป็นการชนกันของ $H$ และ $F$. การต่อข้อมูลยังปรับปรุง ความต้านทานพรีอิมเมจที่สอง: ถ้าคุณรู้ $H(x_1) || F(x_1)$ และคุณต้องการหา $x_2 \n x_1$ ดังนั้น $H(x_1) || F(x_1) = H(x_2) || F(x_2)$คุณต้องหาภาพตัวอย่างที่สองสำหรับทั้งคู่ $F$ และ $H$. สำหรับทั้งความต้านทานการชนกันและความต้านทานพรีอิมเมจที่สอง การต่อเชื่อมอย่างน้อยที่สุดจะแข็งแกร่งพอๆ กับที่อ่อนแอกว่าของทั้งสอง และอาจแข็งแกร่งกว่า
ตัวอย่างที่ใช้การต่อข้อมูลในโปรโตคอลในโลกแห่งความเป็นจริงคือเวอร์ชันที่เก่ากว่าของ โปรโตคอล SSL/TLS, อัพเป็นเวอร์ชั่น 1.1. พวกเขาใช้ MD5(x)||SHA1(x)
สำหรับลายเซ็นจับมือซึ่งประเด็นสำคัญด้านความปลอดภัยคือการต่อต้านภาพที่สอง ทล.1.2 แทนที่สิ่งนี้ด้วยฟังก์ชันแฮชเดียวที่ปรับแต่งได้ (โดยทั่วไปคือ SHA-256 หรือ SHA-384): ความซับซ้อนที่เพิ่มขึ้นนั้นไม่คุ้มค่า (และไม่มีฟังก์ชันแฮชยอดนิยมที่เหมาะสมที่จะรวมเข้ากับ SHA-256 ในเวลานั้น)
การต่อข้อมูลไม่ใช่การชนะที่ชัดเจน ตัวอย่างเช่นมันลดลง แนวต้านพรีอิมเมจแรก ให้กับผู้ที่อ่อนแอกว่าทั้งสองหน้าที่: ถ้าคุณรู้ $H(x) || F(x)$ แล้วคุณจะพบ $x$ หากคุณรู้วิธีการทำเช่นนี้ผ่านทาง $H(x)$ หรือทาง $F(x)$.
Xoring สองแฮช
อีกวิธีหนึ่งในการรวมสองแฮชคือการ xor พวกมัน: $H(x) \oบวก F(x)$. คุณสมบัติความปลอดภัยของผลลัพธ์ขึ้นอยู่กับตัวเลือกของฟังก์ชัน สิ่งนี้มีศักยภาพที่ชัดเจนว่าจะเกิดความผิดพลาดอย่างมหันต์: กรณีพิเศษ $H = F$ ผลลัพธ์ในเอาต์พุตที่เป็นศูนย์บิตทั้งหมด ในทางกลับกัน ถ้า $H$ และ $F$ เป็นอิสระแล้ว $H \oบวก F$ อย่างน้อยก็ดีเท่ากับผู้ที่แข็งแกร่งกว่าของทั้งสองในฐานะออราเคิลแบบสุ่ม ฉันไม่แน่ใจว่ามีเงื่อนไขที่เหมาะสมที่จะรับประกันการต้านทานการชนหรือไม่