สตริงที่แตกต่างกันสองสายสามารถสร้างรหัสแฮช MD5 เดียวกันได้หรือไม่


93

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

คำตอบ:


93

สำหรับทรัพย์สินหลายพันล้านชุดโอกาสที่จะเกิดการชนแบบสุ่มนั้นมีน้อยมาก - ไม่มีอะไรที่คุณต้องกังวล เมื่อพิจารณาถึงความขัดแย้งของวันเกิดชุดของสินทรัพย์ 2 ^ 64 (หรือ 18,446,744,073,709,551,616) ความน่าจะเป็นของการชนกันของ MD5 ครั้งเดียวภายในชุดนี้คือ 50% ในระดับนี้คุณอาจเอาชนะ Google ได้ในแง่ของความจุ

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

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

หากสิ่งเหล่านี้กลายเป็นปัญหาฉันขอแนะนำให้ดูฟังก์ชันแฮชซีรีส์ SHA-2 (SHA-256, SHA-384 และ SHA-512) ข้อเสียคือช้ากว่าเล็กน้อยและมีเอาต์พุตแฮชที่ยาวขึ้น


4
'วัน' เป็นการพูดเกินจริงอย่างมากในตอนนี้อย่างที่ฉันเข้าใจ
Nick Johnson

1
จริงอยู่ฉันอัปเดตโพสต์ของฉัน การโจมตีแบบสุ่มในปี 2004 นั้นรวดเร็วมาก การโจมตีชนกันของคำนำหน้า MD5 ปี 2007 อาจใช้เวลาหลายวัน แต่โดยทั่วไปแล้วจะมีประโยชน์มากกว่าสำหรับผู้โจมตี
intgr

2
ดูคำตอบของ Rubens สำหรับตัวอย่างการทำงานที่จะทำให้เกิดการขัดแย้งกันระหว่างสองไฟล์ปฏิบัติการที่แตกต่างกันในเวลาไม่กี่ชั่วโมง :)
Nick Johnson

38

MD5 เป็นฟังก์ชันแฮชใช่แล้วสตริงที่แตกต่างกันสองสายสามารถสร้างรหัส MD5 ที่ชนกันได้อย่างแน่นอน

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


12

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

ดูสิ่งนี้และคำถามนี้สำหรับตัวอย่าง


1
ความน่าจะเป็นอะไร ที่ชน? ไม่นั่นจะเป็น 1 คือสูงมาก ;-)
Konrad Rudolph

ดีจริง มีสองสายที่มีแฮช MD5 เดียวกัน
sharptooth

3
ฉันรู้จักสิ่งนี้ในชื่อปัญหานกพิราบ
Daniel

ปัญหาวันเกิดเกี่ยวข้องกับการปะทะกัน สำหรับการพิสูจน์ต้องมีสิ่งที่คุณต้องการหลักการหลุม pidgeon
jk

ฉันจะโหวตคำตอบของคุณสองครั้งถ้าทำได้ เรากำลังพูดถึงความน่าจะเป็น "ต่ำ" แค่ไหน?
Alex Spencer

10

ใช่แน่นอน: แฮช MD5 มีความยาว จำกัด แต่มีสตริงอักขระที่เป็นไปได้ไม่ จำกัด จำนวนที่สามารถแฮช MD5 ได้


10

ใช่เป็นไปได้ว่าสตริงที่แตกต่างกันสองสายสามารถสร้างรหัสแฮช MD5 เดียวกันได้

นี่คือการทดสอบง่ายๆโดยใช้ข้อความไบนารีที่คล้ายกันมากในสตริงเลขฐานสิบหก:

$ echo '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
c6b384c4968b28812b676b49d40c09f8af4ed4cc  -
008ee33a9d58b51cfeb425b0959121c9

$ echo '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
c728d8d93091e9c7b87b43d9e33829379231d7ca  -
008ee33a9d58b51cfeb425b0959121c9

พวกเขาสร้างผลรวม SHA-1 ที่แตกต่างกัน แต่ค่าแฮช MD5 เท่ากัน ประการที่สองสตริงมีความคล้ายคลึงกันมากดังนั้นจึงยากที่จะหาความแตกต่างระหว่างสตริงเหล่านี้

ความแตกต่างสามารถพบได้โดยคำสั่งต่อไปนี้:

$ diff -u <(echo 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2 | fold -w2) <(echo 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2 | fold -w2)
--- /dev/fd/63  2016-02-05 12:55:04.000000000 +0000
+++ /dev/fd/62  2016-02-05 12:55:04.000000000 +0000
@@ -33,7 +33,7 @@
 af
 bf
 a2
-00
+02
 a8
 28
 4b
@@ -53,7 +53,7 @@
 6d
 a0
 d1
-55
+d5
 5d
 83
 60

ตัวอย่างการชนกันข้างต้นนำมาจาก Marc Stevens: Single-block collision สำหรับ MD5 , 2012; เขาอธิบายวิธีการของเขาพร้อมซอร์สโค้ด ( ลิงค์สำรองไปยังกระดาษ )


การทดสอบอื่น:

$ echo '0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
756f3044edf52611a51a8fa7ec8f95e273f21f82  -
cee9a457e790cf20d4bdaa6d69f01e41

$ echo '0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
6d5294e385f50c12745a4d901285ddbffd3842cb  -
cee9a457e790cf20d4bdaa6d69f01e41

ผลรวม SHA-1 ที่แตกต่างกันแฮช MD5 เดียวกัน

ความแตกต่างอยู่ในหนึ่งไบต์:

$ diff -u <(echo 0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef | fold -w2) <(echo 0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef | fold -w2)
--- /dev/fd/63  2016-02-05 12:56:43.000000000 +0000
+++ /dev/fd/62  2016-02-05 12:56:43.000000000 +0000
@@ -19,7 +19,7 @@
 03
 65
 9e
-70
+74
 4f
 85
 34
@@ -41,7 +41,7 @@
 a3
 f4
 15
-5c
+dc
 bb
 86
 07

ตัวอย่างด้านบนดัดแปลงมาจาก Tao Xie และ Dengguo Feng: สร้างการชนกันของ MD5 โดยใช้เพียงบล็อกข้อความเดียว 2010


ที่เกี่ยวข้อง:


4

ใช่มันเป็นไปได้ มันจะเรียกว่าการปะทะกันยุ่งเหยิง

ต้องบอกว่าอัลกอริทึมเช่น MD5 ได้รับการออกแบบมาเพื่อลดโอกาสที่จะเกิดการชนกันให้เหลือน้อยที่สุด

รายการ Wikipedia บนMD5อธิบายถึงช่องโหว่บางอย่างใน MD5 ซึ่งคุณควรระวัง


4

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

การคาดคะเนในวิกิพีเดีย

แก้ไข: เพื่อให้มีฟังก์ชั่นแฮชฉีดที่สมบูรณ์มีอยู่: เรียกว่าPerfect hashingเพอร์เฟคร่ำเครียด


1
ไม่มีฟังก์ชันแฮชที่สมบูรณ์แบบเมื่อขนาดเอาต์พุตเล็กกว่าขนาดอินพุต
Paŭlo Ebermann

3

ใช่แล้ว! การชนกันจะเป็นไปได้ (แม้ว่าความเสี่ยงจะน้อยมากก็ตาม) ถ้าไม่คุณจะมีวิธีการบีบอัดที่ได้ผลดีทีเดียว!

แก้ไข : ตามที่ Konrad Rudolph กล่าวว่า: ชุดอินพุตที่ไม่ จำกัด ที่อาจแปลงเป็นชุดเอาต์พุตที่ จำกัด (32 ตัวอักษร hex) จะส่งผลให้เกิดการชนกันอย่างไม่มีที่สิ้นสุด


3

อย่างที่คนอื่นบอกใช่อาจมีการชนกันระหว่างอินพุตที่แตกต่างกันสองอินพุต อย่างไรก็ตามในกรณีการใช้งานของคุณฉันไม่เห็นว่าเป็นปัญหา ฉันสงสัยอย่างมากว่าคุณจะเกิดการชนกัน - ฉันใช้ MD5 ในการพิมพ์ลายนิ้วมือไฟล์ภาพหลายแสนไฟล์ในรูปแบบรูปภาพ (JPG, บิตแมป, PNG, ดิบ) ในงานก่อนหน้านี้และฉันไม่มีการชนกัน .

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


1
อันที่จริงหากผู้โจมตีสามารถสร้างการชนกันด้วยอัลกอริทึมแฮชหนึ่งอัลกอริทึมเขาสามารถใช้สิ่งนี้เพื่อรับการชนกันสำหรับอัลกอริทึมที่สอง นี้ถูกกล่าวถึงเมื่อเร็ว ๆ นี้คำถามของฉันที่ crypto.stackexchange
Paŭlo Ebermann

2

ฉันรู้ว่านี่เป็นเรื่องเก่า แต่คิดว่าฉันจะช่วยแก้ปัญหาของฉัน มีการผสมแฮชที่เป็นไปได้ 2 ^ 128 ดังนั้นความน่าจะเป็น 2 ^ 64 ของความขัดแย้งในวันเกิด แม้ว่าวิธีแก้ไขด้านล่างจะไม่สามารถขจัดความเป็นไปได้ที่จะเกิดการชนกัน แต่ก็จะช่วยลดความเสี่ยงได้อย่างมาก

2^64 = 18,446,744,073,709,500,000 possible combinations

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

ดังนั้นรหัสหลอกของฉันสำหรับสิ่งนี้คือ:

Result = Hash(string) & Hash(Reverse(string)) & Hash(Length(string))

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

Result = Hash(string) & Hash(Reverse(string)) & Hash(Length(string)) 
         & Hash(Reverse(SpellOutLengthWithWords(Length(string)))) 
         & Hash(Rotate13(string)) Hash(Hash(string)) & Hash(Reverse(Hash(string)))

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

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

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

2^64 (or 18,446,744,073,709,551,616) 

มีแนวโน้มที่จะเพิ่มขึ้นเป็นร้อยหลัก ค่าสูงสุดทางทฤษฎีนี้สามารถให้คุณได้

จำนวนสตริงผลลัพธ์ที่เป็นไปได้:

528294531135665246352339784916516606518847326036121522127960709026673902556724859474417255887657187894674394993257128678882347559502685537250538978462939576908386683999005084168731517676426441053024232908211188404148028292751561738838396898767036476489538580897737998336


1

ฉันคิดว่าเราต้องระมัดระวังในการเลือกอัลกอริทึมการแฮชตามความต้องการของเราเนื่องจากการชนกันของแฮชไม่ได้หายากอย่างที่ฉันคาดไว้ ฉันเพิ่งพบกรณีการชนกันของแฮชในโปรเจ็กต์ของฉันที่ง่ายมาก ฉันใช้ Python wrapper ของ xxhash สำหรับการแฮช ลิงก์: https://github.com/ewencp/pyhashxx

s1 = 'mdsAnalysisResult105588'
s2 = 'mdsAlertCompleteResult360224'
pyhashxx.hashxx(s1) # Out: 2535747266
pyhashxx.hashxx(s2) # Out: 2535747266

มันทำให้เกิดปัญหาการแคชที่ยุ่งยากมากในระบบจากนั้นในที่สุดฉันก็พบว่ามันเกิดการชนกันของแฮช

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