Git จะจัดการกับการชน SHA-1 บนหยดได้อย่างไร


543

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

ช่วยพัฒนาสมองมากกว่าปัญหาจริง แต่ฉันพบว่าปัญหาน่าสนใจ


76
เมื่อพัฒนาสมองตอนนี้อาจเป็นปัญหาที่เกิดขึ้นจริง
Toby

11
@Toby คำถามนี้เป็นเรื่องเกี่ยวกับการโจมตีก่อนภาพ ; สิ่งที่ Google แสดงให้เห็นคือการโจมตีการชน - คล้ายกัน แต่แตกต่างกันเล็กน้อย คุณสามารถอ่านเพิ่มเติมเกี่ยวกับความแตกต่างที่นี่
Saheed

@ ซาฮิดฉันไม่เห็นว่าส่วนใดของคำถามนี้เกี่ยวกับการโจมตีล่วงหน้าสำหรับรูปภาพโดยเฉพาะเนื่องจากคำถามที่โพสต์นั้นเกี่ยวกับการชนในพื้นที่เก็บข้อมูลคอมไพล์ไม่ใช่เกี่ยวกับการใช้ประโยชน์จากมัน
Toby

3
@Toby ผู้ช่วยพัฒนาสมองดั้งเดิมไม่ได้เกี่ยวกับการโจมตี (ไม่ใช่ภาพก่อนหรือการชน) แต่เกี่ยวกับการปะทะกันโดยไม่ตั้งใจซึ่งไม่น่าคิดเลยว่ามันจะไม่คุ้มค่าที่จะพิจารณา ฉันคิดว่าสิ่งที่ Saheed พยายามพูดอย่างถูกต้องนั้นยังไม่เป็นปัญหาจริง อย่างไรก็ตามคุณมีสิทธิ์ที่การโจมตีของ Google อาจก่อให้เกิดปัญหาด้านความปลอดภัยขึ้นอยู่กับการใช้ Git
Andrew W. Phillips

นี่คือการปะทะกันครั้งที่สองที่มีเพียง 320 bytes privacylog.blogspot.com/2019/12/the-second-sha-collision.html
William Entriken

คำตอบ:


736

ฉันทำการทดลองเพื่อค้นหาว่า Git จะทำงานอย่างไรในกรณีนี้ นี่คือกับรุ่น 2.7.9 ~ rc0 + next.20151210 (รุ่นเดเบียน) ฉันเพียงแค่ลดขนาดแฮชจาก 160 บิตเป็น 4 บิตโดยใช้ diff และ git ที่สร้างใหม่:

--- git-2.7.0~rc0+next.20151210.orig/block-sha1/sha1.c
+++ git-2.7.0~rc0+next.20151210/block-sha1/sha1.c
@@ -246,6 +246,8 @@ void blk_SHA1_Final(unsigned char hashou
    blk_SHA1_Update(ctx, padlen, 8);

    /* Output hash */
-   for (i = 0; i < 5; i++)
-       put_be32(hashout + i * 4, ctx->H[i]);
+   for (i = 0; i < 1; i++)
+       put_be32(hashout + i * 4, (ctx->H[i] & 0xf000000));
+   for (i = 1; i < 5; i++)
+       put_be32(hashout + i * 4, 0);
 }

จากนั้นฉันก็ลงมือทำบางอย่างและสังเกตสิ่งต่อไปนี้

  1. หากหยดนั้นมีแฮชเดียวกันอยู่แล้วคุณจะไม่ได้รับคำเตือนใด ๆ เลย ทุกอย่างดูเหมือนจะโอเค แต่เมื่อคุณกดโคลนนิ่งบางคนหรือเปลี่ยนกลับคุณจะสูญเสียเวอร์ชันล่าสุด (ตามที่อธิบายไว้ด้านบน)
  2. หากวัตถุต้นไม้มีอยู่แล้วและคุณสร้างหยดที่มีแฮชเดียวกัน: ทุกอย่างดูเหมือนจะเป็นเรื่องปกติจนกว่าคุณจะพยายามที่จะผลักดันหรือบางคนโคลนที่เก็บของคุณ จากนั้นคุณจะเห็นว่า repo เสียหาย
  3. หากมีวัตถุกระทำอยู่แล้วและคุณสร้างหยดที่มีแฮชเดียวกันนั่นคือ # 2 - เสียหาย
  4. หากมี Blob อยู่แล้วและคุณสร้างวัตถุที่มีแฮชเดียวกันมันจะล้มเหลวเมื่อทำการอัพเดท "ref"
  5. หากมีหยดอยู่แล้วและคุณสร้างวัตถุต้นไม้ด้วยแฮชเดียวกัน มันจะล้มเหลวเมื่อสร้างความมุ่งมั่น
  6. หากวัตถุต้นไม้มีอยู่แล้วและคุณทำการกระทำวัตถุที่มีแฮชเดียวกันวัตถุนั้นจะล้มเหลวเมื่อทำการอัพเดท "ref"
  7. หากวัตถุต้นไม้มีอยู่แล้วและคุณสร้างวัตถุต้นไม้ที่มีแฮชเดียวกันทุกอย่างจะดูโอเค แต่เมื่อคุณส่งมอบพื้นที่เก็บข้อมูลทั้งหมดจะอ้างอิงต้นไม้ที่ไม่ถูกต้อง
  8. หากมีวัตถุกระทำอยู่แล้วและคุณสร้างวัตถุส่งสารที่มีแฮชเดียวกันทุกอย่างจะดูโอเค แต่เมื่อคุณคอมมิชชันคอมมิทจะไม่ถูกสร้างขึ้นและพอยน์เตอร์ HEAD จะถูกย้ายไปที่คอมมิชชันเก่า
  9. หากมีวัตถุกระทำอยู่แล้วและคุณสร้างวัตถุต้นไม้ที่มีแฮชเดียวกันวัตถุนั้นจะล้มเหลวเมื่อสร้างการกระทำ

สำหรับ # 2 คุณจะได้รับข้อผิดพลาดเช่นนี้เมื่อคุณเรียกใช้ "git push":

error: object 0400000000000000000000000000000000000000 is a tree, not a blob
fatal: bad blob object
error: failed to push some refs to origin

หรือ:

error: unable to read sha1 file of file.txt (0400000000000000000000000000000000000000)

หากคุณลบไฟล์แล้วเรียกใช้ "git checkout file.txt"

สำหรับ # 4 และ # 6 โดยทั่วไปคุณจะได้รับข้อผิดพลาดดังนี้:

error: Trying to write non-commit object
f000000000000000000000000000000000000000 to branch refs/heads/master
fatal: cannot update HEAD ref

เมื่อใช้งาน "git commit" ในกรณีนี้คุณสามารถพิมพ์ "git commit" อีกครั้งเนื่องจากจะสร้างแฮชใหม่ (เนื่องจากการประทับเวลาที่เปลี่ยนแปลง)

สำหรับ # 5 และ # 9 คุณจะได้รับข้อผิดพลาดดังนี้:

fatal: 1000000000000000000000000000000000000000 is not a valid 'tree' object

เมื่อใช้งาน "git commit"

หากมีคนพยายามโคลนที่เก็บข้อมูลที่เสียหายของคุณพวกเขามักจะเห็นสิ่งต่อไปนี้:

git clone (one repo with collided blob,
d000000000000000000000000000000000000000 is commit,
f000000000000000000000000000000000000000 is tree)

Cloning into 'clonedversion'...
done.
error: unable to read sha1 file of s (d000000000000000000000000000000000000000)
error: unable to read sha1 file of tullebukk
(f000000000000000000000000000000000000000)
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry the checkout with 'git checkout -f HEAD'

สิ่งที่ "กังวล" คือในสองกรณี (2,3) พื้นที่เก็บข้อมูลเสียหายโดยไม่มีคำเตือนใด ๆ และใน 3 กรณี (1,7,8) ทุกอย่างดูโอเค แต่เนื้อหาที่เก็บแตกต่างจากที่คุณคาดหวัง เป็น. คนที่โคลนหรือดึงจะมีเนื้อหาที่แตกต่างจากสิ่งที่คุณมี เคส 4,5,6 และ 9 ใช้ได้เนื่องจากจะหยุดโดยมีข้อผิดพลาด ฉันคิดว่ามันจะดีกว่าถ้ามันล้มเหลวด้วยข้อผิดพลาดอย่างน้อยในทุกกรณี


157
คำตอบที่ยอดเยี่ยม - ลดขนาดแฮชเพื่อดูว่าจริงแล้วมันทำงานอย่างไรเป็นความคิดที่ดี
Gnurou

4
@Gurur ฉันเห็นด้วยและไม่ได้ตอบคำถามในเวลานั้น กรณีเหล่านี้ถูกกล่าวถึงในรายชื่อส่งเมล git หรือไม่?
VonC

1
เป็นไปได้มากขนาดนี้ที่เกิดขึ้นจริงโดยไม่ลดขนาดแฮช
Mathias Bader

4
นอกจากนี้แผนอะไรถ้ามีการย้ายไปยังอัลกอริทึมการแปลงแป้นพิมพ์อื่น
Pete

9
ต้องอ่าน - คำอธิบายของ Linus
Torval

238

คำตอบเดิม (2012) (ดูshattered.ioการปะทะกันของ SHA1 2017 ด้านล่าง)

ที่เก่า (2006) คำตอบจากไลนัสยังอาจจะเกี่ยวข้อง:

Nope หากมี SHA1 เหมือนกันก็หมายความว่าเมื่อเราได้รับวัตถุจากส่วนอื่น ๆ เราจะไม่เขียนทับวัตถุที่เรามีอยู่แล้ว

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

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

ดังนั้นคุณมีการชนกันสองกรณี:

  • ชนิดโดยไม่ได้ตั้งใจที่คุณอย่างใดมีความโชคร้ายมากและแฟ้มที่สองจบลงด้วยการมี SHA1 เดียวกัน
    ณ จุดนั้นสิ่งที่เกิดขึ้นคือเมื่อคุณส่งไฟล์นั้น (หรือgit-update-indexย้ายไฟล์ไปยังดัชนี แต่ยังไม่ได้ทำ) SHA1 ของเนื้อหาใหม่จะถูกคำนวณ แต่เนื่องจากตรงกับวัตถุเก่า วัตถุใหม่จะไม่ถูกสร้างขึ้นและกระทำหรือดัชนีจบลงด้วยการชี้ไปที่เก่าวัตถุ
    คุณจะไม่สังเกตเห็นทันที (เนื่องจากดัชนีจะตรงกับวัตถุเก่า SHA1 และนั่นหมายความว่าบางสิ่งเช่น " git diff" จะใช้สำเนาที่เช็คเอาท์) แต่ถ้าคุณทำระดับต้นไม้ที่แตกต่างกัน (หรือคุณทำโคลน หรือดึงหรือบังคับให้ชำระเงิน) คุณจะสังเกตเห็นว่าไฟล์นั้นมีการเปลี่ยนแปลงบางอย่างแตกต่างจากที่คุณคาดไว้อย่างสิ้นเชิง
    ดังนั้นโดยทั่วไปคุณจะสังเกตเห็นการชนแบบนี้ค่อนข้างเร็ว
    ในข่าวที่เกี่ยวข้องคำถามคือสิ่งที่ต้องทำเกี่ยวกับการปะทะกันโดยไม่ตั้งใจ ..
    ก่อนอื่นผมขอเตือนผู้คนว่าการปะทะโดยไม่ตั้งใจนั้นเป็นเรื่องจริงจริง ๆไม่น่าแช่งจริง ๆดังนั้นเราจะไม่เคยเห็นมันในประวัติศาสตร์ ของจักรวาล
    แต่ถ้ามันเกิดขึ้นมันไม่ใช่จุดจบของโลก: สิ่งที่คุณน่าจะต้องทำก็แค่เปลี่ยนไฟล์ที่ชนกันเล็กน้อยและแค่บังคับคอมมิทใหม่กับเนื้อหาที่ถูกเปลี่ยน (เพิ่มความคิดเห็นโดยบอกว่า " /* This line added to avoid collision */") และ จากนั้นสอนคอมไพล์เกี่ยวกับเวทย์มนตร์ SHA1 ที่แสดงให้เห็นว่าเป็นอันตราย
    ดังนั้นสองสามล้านปีเราอาจจะต้องเพิ่มค่า SHA1“ พิษ” หนึ่งหรือสองค่าลงในคอมไพล์ ไม่น่าจะเป็นปัญหาการบำรุงรักษามาก)

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

คำถามของการใช้ SHA-256ถูกกล่าวถึงเป็นประจำ แต่ไม่กระทำการใดสำหรับในตอนนี้ (2012)
หมายเหตุ: เริ่มต้นปี 2018 และ Git 2.19รหัสจะถูก refactored เพื่อใช้ SHA-256


หมายเหตุ (ขำขัน): คุณสามารถบังคับให้มีการกระทำเพื่อ SHA1 โดยเฉพาะอย่างยิ่งคำนำหน้ากับโครงการgitbruteจากแบรดฟิทซ์ (bradfitz )

gitbrute brute บังคับให้คู่ของผู้แต่ง + การประทับเวลาของคอมมิทเตอร์ที่คอมมิทที่เกิดขึ้นมีคำนำหน้าที่คุณต้องการ

ตัวอย่าง: https://github.com/bradfitz/deadbeef


แดเนียล Dinnyesชี้ให้เห็นในความคิดเห็นไป7.1 Git เครื่องมือ - Revision เลือกซึ่งรวมถึง:

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


ยิ่งเมื่อเร็ว ๆ นี้ (กุมภาพันธ์ 2017) shattered.ioแสดงให้เห็นถึงความเป็นไปได้ของการปลอมแปลงการชน SHA1:
(ดูคำตอบที่แยกต่างหากของฉันรวมถึงโพสต์ Google+ ของ Linus Torvalds)

  • a / ยังต้องใช้การคำนวณ SHA1 มากกว่า 9,223,372,036,854,775,808 สิ่งนี้ใช้พลังการประมวลผลเทียบเท่ากับการคำนวณด้วย CPU เดี่ยว 6,500 ปีและการคำนวณ GPU เดี่ยว 110 ปี
  • b / จะปลอมแปลงไฟล์หนึ่งไฟล์ (ที่มี SHA1 เหมือนกัน) แต่ด้วยข้อ จำกัด เพิ่มเติมที่เนื้อหาและขนาดของมันจะสร้าง SHA1 ที่เหมือนกัน (การชนกับเนื้อหาเพียงอย่างเดียวไม่เพียงพอ): ดู " วิธีคำนวณ git hash คืออะไร ") กSHA1 หยดคำนวณขึ้นอยู่กับเนื้อหาและขนาด

ดู " อายุการใช้งานฟังก์ชันแฮชการเข้ารหัส " จากValerie Anita Auroraสำหรับข้อมูลเพิ่มเติม
ในหน้านั้นเธอบันทึก:

Google ใช้เวลา CPU 6500 ปีและ GPU 110 ปีเพื่อโน้มน้าวให้ทุกคนที่เราต้องหยุดใช้ SHA-1 สำหรับแอปพลิเคชันที่สำคัญด้านความปลอดภัย
ก็เพราะมันเท่ห์

ดูข้อมูลเพิ่มเติมในของฉันคำตอบที่แยกจากกันดังต่อไปนี้


25
บิด: ยังคงแฮชเหมือนเดิมหลังจากเพิ่ม/* This line added to avoid collision */: D คุณสามารถลอตเตอรี่ได้สองครั้ง: P
Janus Troelsen

4
@ JanusTroelsen แน่นอน แต่มันยังเป็นลอตเตอรีใช่มั้ย ;) (ดังที่กล่าวไว้ในบันทึกย่อสั้น ๆ เกี่ยวกับ SHA1 )
VonC

6
@VonC เกี่ยวกับการอ้างอิงนั้น : เป็นการระเบิดของมนุษย์หมาป่าที่แพร่ระบาดทั่วโลก - กำจัดมนุษย์ทั้งหมดและทำให้เกิดการตายอย่างน่าสยดสยองของนักพัฒนาทั้งหมดของฉันในคืนเดียวกันแม้ว่าพวกเขาจะกระจายทางภูมิศาสตร์ - ถือว่าเป็นเหตุการณ์ที่ไม่เกี่ยวข้องหรือไม่? แน่นอนว่ามันเกิดขึ้นในคืนพระจันทร์เต็มดวง ตอนนี้สถานการณ์ดังกล่าวจะเปลี่ยนแปลงสิ่งต่าง ๆ แม้แต่การคิดเกี่ยวกับมันก็เป็นบ้า! นั่นคือความน่าจะเป็นในระดับที่แตกต่างกันโดยสิ้นเชิง! นั่นหมายความว่าเราต้อง ... หยุดใช้ GIT! ตอนนี้ !!! ทุกคน RUUUUUN !!!!!!!
Daniel Dinnyes

2
โปรดทราบว่า gitbrute ไม่ได้บังคับเฉพาะ SHA1 แต่เป็นเพียงคำนำหน้าเท่านั้น (เช่นส่วนย่อยของ SHA1 ทั้งหมด) การบังคับให้ SHA1 ทั้งหมด (เช่นมีส่วนนำหน้ายาวเต็มของคีย์) อาจใช้เวลานานเกินไป
mb14

2
@JanusTroelsen จากนั้นคุณจะเพิ่ม:/* This line added to avoid collision of the avoid collision line */
smg

42

ตามPro Git :

หากคุณบังเอิญส่งมอบวัตถุที่แฮชไปยังค่า SHA-1 เช่นเดียวกับวัตถุก่อนหน้าในที่เก็บของคุณ Git จะเห็นวัตถุก่อนหน้านี้อยู่ในฐานข้อมูล Git ของคุณแล้วและคิดว่ามันถูกเขียนไปแล้ว หากคุณพยายามที่จะตรวจสอบวัตถุนั้นอีกครั้งในบางจุดคุณจะได้รับข้อมูลของวัตถุแรกเสมอ

ดังนั้นมันจะไม่ล้มเหลว แต่จะไม่บันทึกวัตถุใหม่ของคุณด้วย
ฉันไม่ทราบว่าจะมีลักษณะอย่างไรในบรรทัดคำสั่ง แต่จะทำให้สับสน

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

ต่อไปนี้เป็นตัวอย่างเพื่อให้คุณทราบถึงสิ่งที่จะได้รับการชน SHA-1 ถ้ามนุษย์ทั้งหมด 6.5 พันล้านคนบนโลกเขียนโปรแกรมและทุก ๆ วินาทีแต่ละคนก็สร้างรหัสที่เทียบเท่ากับประวัติเคอร์เนลของลินุกซ์ทั้งหมด (1 ล้านวัตถุ Git) และผลักมันลงในที่เก็บ Git อันยิ่งใหญ่มันใช้เวลา 5 ปี ที่เก็บนั้นมีวัตถุมากพอที่จะมีโอกาส 50% ของการชนกันของวัตถุ SHA-1 เดียว มีความเป็นไปได้สูงที่สมาชิกในทีมของคุณทุกคนจะถูกโจมตีและถูกสังหารโดยหมาป่าในเหตุการณ์ที่ไม่เกี่ยวข้องในคืนเดียวกัน


44
ฉันต้องการดูแหล่งที่มาของตัวเลขในประโยคสุดท้าย ;-)
Joachim Sauer

17
@Jasper: การเชื่อมโยงที่เป็นเอกสารที่ดี แต่มันก็ไม่ได้มีสถิติความน่าจะเป็นของสมาชิกคนหนึ่งของทีมงานทุกคนถูกทำร้ายและถูกฆ่าโดยหมาป่าในเหตุการณ์ที่เกิดขึ้นที่ไม่เกี่ยวข้องกันในคืนเดียวกัน
Joachim Sauer

5
@ แจสเปอร์: วิธีที่ฉันอ่านมันแท้จริงข้อความอ้างว่าความน่าจะเป็นของสมาชิกทีม 6.5 พันล้านคนที่ถูกหมาป่าสังหารในคืนเดียวกันนั้นสูงกว่า 50% แต่คัดค้านหลักของฉันไปที่คำพูดของเขาก็คือว่าเหตุการณ์ดังกล่าวจะมี การจะเป็นปรากฏการณ์ทั่วโลก; เป็นไปไม่ได้ที่เหตุการณ์นี้จะเกิดขึ้นเนื่องจากเหตุการณ์ที่ไม่เกี่ยวข้อง ;)
Keith Robertson

5
@ KeithRobertson ฉันค่อนข้างมั่นใจว่าโพสต์กำลังพูดถึงโอกาสที่สมาชิกในทีมของคุณจะถูกกินเมื่อเปรียบเทียบกับโอกาสที่จะมีการชนกันของข้อมูลหากทุกคนในโลกผลิตรหัสที่บ้าไปตามเวลาที่ใช้ รับโอกาส 50% ของการชน (เช่นเหตุการณ์หมาป่าไม่ได้เกี่ยวข้องกับทั้งโลกและ 50% แยกจากหมาป่า) คุณได้รับจุดแม้ว่าถ้าเหตุการณ์ดังกล่าวเป็นไปไม่ได้ดังนั้นการชนกันของ git hash ควรจะเป็นเช่นนั้น (แน่นอนหนึ่งคือ (เกือบ) โอกาสตามหมดจดและอื่น ๆ ไม่ได้ แต่ยังคง.)
แจสเปอร์


23

เพื่อเพิ่มคำตอบก่อนหน้าของฉันจาก 2012ตอนนี้มี (ก.พ. 2560 ห้าปีต่อมา) ตัวอย่างของการชนกันของ SHA-1 ที่เกิดขึ้นจริงกับshattered.ioซึ่งคุณสามารถสร้างไฟล์ PDF ที่ขัดแย้งกันสองไฟล์: ที่ได้รับ SHA- 1 ลายเซ็นดิจิทัลในไฟล์ PDF ไฟล์แรกซึ่งสามารถใช้เป็นลายเซ็นที่ถูกต้องในไฟล์ PDF ที่สอง
ดูที่ " ที่ประตูแห่งความตายมาหลายปีฟังก์ชั่น SHA1 ที่ใช้กันอย่างแพร่หลายตอนนี้ตายแล้ว " และภาพประกอบนี้

อัปเดต 26 กุมภาพันธ์: Linus ยืนยันประเด็นต่อไปนี้ในโพสต์ Google+ :

(1) ก่อนอื่น - ท้องฟ้าไม่ตก มีความแตกต่างอย่างมากระหว่างการใช้แฮชการเข้ารหัสสำหรับสิ่งต่าง ๆ เช่นการเซ็นชื่อเพื่อความปลอดภัยและการใช้แฮชเพื่อสร้าง "ตัวระบุเนื้อหา" สำหรับระบบที่ระบุเนื้อหาได้เช่น git

(2) ประการที่สองลักษณะของการโจมตีโดยเฉพาะของ SHA1 นี้หมายความว่าจริงๆแล้วมันง่ายในการบรรเทาและมีแพทช์สองชุดที่โพสต์สำหรับการบรรเทานั้น

(3) และสุดท้ายมีการเปลี่ยนไปใช้แฮชอื่น ๆ ที่ไม่ทำให้โลกแตกสลาย - หรือแม้แต่คลังเก็บ Git เก่า ๆ

เกี่ยวกับช่วงการเปลี่ยนภาพให้ดูไตรมาส 1 ปี 2018 Git 2.16เพิ่มโครงสร้างที่แสดงอัลกอริธึมการแฮช การดำเนินการของการเปลี่ยนแปลงนั้นได้เริ่มขึ้นแล้ว

เริ่มต้น Git 2.19 (ไตรมาสที่ 3 ปี 2018) Git ได้เลือกSHA-256 เป็น NewHashและอยู่ในขั้นตอนการรวมเข้ากับรหัส (หมายถึง SHA1 ยังคงเป็นค่าเริ่มต้น (Q2 2019, Git 2.21) แต่ SHA2 จะเป็นตัวตายตัวแทน)


คำตอบเดิม (25 กุมภาพันธ์) แต่:

  • สิ่งนี้อนุญาตให้มีการหลอมเป็นหยด แต่ต้น SHA-1 ของต้นไม้จะยังคงมีการเปลี่ยนแปลงเนื่องจากขนาดของก้อนที่ปลอมแปลงอาจไม่เหมือนกับของเดิม: ดู " วิธีคำนวณ git hash เป็นอย่างไร "; SHA1 หยดคำนวณขึ้นอยู่กับเนื้อหาและขนาด
    มันจะมีปัญหาบางอย่างสำหรับgit-svnแม้ว่า หรือมากกว่ากับ SVN ตัวเองเป็นที่เห็นนี่
  • ดังที่ฉันได้กล่าวไปแล้วในคำตอบเดิมของฉันความพยายามดังกล่าวยังคงเป็นข้อห้ามสำหรับตอนนี้ (6,500 CPU ปีและ 100 GPU ปี) ดูValerie Anita Auroraใน " อายุการใช้งานฟังก์ชันแฮชการเข้ารหัส "
  • ในฐานะที่เป็นความเห็นก่อนหน้านี้ไม่ได้เกี่ยวกับการรักษาความปลอดภัยหรือความไว้วางใจ แต่ความสมบูรณ์ของข้อมูล (de ซ้ำและการตรวจสอบข้อผิดพลาด) ซึ่งสามารถตรวจพบได้ง่ายโดยgit fsckเป็นที่กล่าวถึงโดย Linus Torvaldsวันนี้ git fsckจะเตือนเกี่ยวกับข้อความยืนยันที่มีข้อมูลทึบแสงซ่อนอยู่หลังจากNUL(แม้ว่าNULจะไม่ปรากฏในไฟล์ที่เป็นการฉ้อโกง )
    ไม่ใช่ทุกคนที่เปิดใช้transfer.fsckแต่ GitHub ทำ: การกดใด ๆ จะถูกยกเลิกในกรณีของวัตถุที่มีรูปแบบไม่ถูกต้องหรือลิงก์ที่ใช้งานไม่ได้ ... ถึงแม้ว่าจะมีเหตุผลนี้ไม่ได้เปิดใช้งานโดยค่าเริ่มต้น
  • ไฟล์ pdf สามารถมีข้อมูลไบนารีโดยพลการที่คุณสามารถเปลี่ยนเพื่อสร้าง SHA-1 ที่ขัดแย้งกันซึ่งต่างจากซอร์สโค้ดที่ปลอมแปลง
    ปัญหาที่เกิดขึ้นจริงในการสร้างสองที่เก็บ Git ที่มีหัวเดียวกันกระทำการแฮชและเนื้อหาที่แตกต่างกัน และแม้แล้วที่ยังคงโจมตีที่ซับซ้อน
  • Linus เพิ่ม :

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

Joey Hessพยายาม pdf เหล่านั้นในrepo Gitและเขาพบว่า :

ซึ่งรวมถึงสองไฟล์ที่มี SHA และขนาดเดียวกันซึ่งจะได้รับ blobs ที่แตกต่างกันด้วยวิธีการคอมไพล์เตรียมส่วนหัวของเนื้อหา

joey@darkstar:~/tmp/supercollider>sha1sum  bad.pdf good.pdf 
d00bbe65d80f6d53d5c15da7c6b4f0a655c5a86a  bad.pdf
d00bbe65d80f6d53d5c15da7c6b4f0a655c5a86a  good.pdf
joey@darkstar:~/tmp/supercollider>git ls-tree HEAD
100644 blob ca44e9913faf08d625346205e228e2265dd12b65    bad.pdf
100644 blob 5f90b67523865ad5b1391cb4a1c010d541c816c1    good.pdf

ในขณะที่การผนวกข้อมูลที่เหมือนกันกับไฟล์ที่มีการชนกันเหล่านี้จะสร้างการชนอื่น ๆ แต่การเตรียมข้อมูลไม่ได้

ดังนั้นเวกเตอร์หลักของการโจมตี (การปลอมแปลงคอมมิท) จะเป็น :

  • สร้างวัตถุกระทำปกติ
  • ใช้วัตถุกระทำทั้งหมด + NUL เป็นคำนำหน้าที่เลือกและ
  • ใช้การโจมตีการชนกันของคำนำหน้าเพื่อสร้างวัตถุดี / ไม่ดีในการชนกัน
  • ... และสิ่งนี้ไร้ประโยชน์เพราะความดีและไม่ดียังคงชี้ไปที่ต้นไม้ต้นเดียวกัน!

นอกจากนี้คุณสามารถและตรวจจับการโจมตีของการเข้ารหัสลับแบบเข้ารหัสลับกับ SHA-1 ที่มีอยู่ในแต่ละไฟล์ด้วย cr-marcstevens/sha1collisiondetection

เพิ่มการตรวจสอบที่คล้ายกันใน Git ตัวเองจะมีค่าใช้จ่ายในการคำนวณบาง

ในการเปลี่ยนแฮชข้อคิดเห็น Linux :

ขนาดของแฮชและตัวเลือกของอัลกอริทึมแฮชเป็นปัญหาอิสระ
สิ่งที่คุณอาจทำคือสลับไปใช้แฮช 256 บิตใช้งานภายในและในฐานข้อมูล git ดั้งเดิมจากนั้นแสดงแฮชเป็นสตริง hex แบบ 40 ตัวอักษรโดยค่าเริ่มต้นเท่านั้น หลายสถานการณ์)
วิธีการที่เครื่องมือรอบ ๆ คอมไพล์ไม่เห็นการเปลี่ยนแปลงนอกจากจะผ่านการ--full-hashโต้แย้งพิเศษ " " (หรือ " --abbrev=64" หรืออะไรก็ตาม - ค่าปริยายที่เราย่อมาถึง 40)

ถึงกระนั้นแผนการเปลี่ยนผ่าน (จาก SHA1 ไปยังฟังก์ชันแฮชอื่น) จะยังคงซับซ้อนแต่ก็มีการศึกษาอย่างแข็งขัน แคมเปญคือในความคืบหน้า :
convert-to-object_id


อัปเดตวันที่ 20 มีนาคม: GitHub ให้รายละเอียดการโจมตีที่เป็นไปได้และการป้องกัน :

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

การป้องกัน:

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

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

ดู " sha1collisiondetection" โดยMarc Stevens


อีกครั้งในไตรมาสที่ 1 ปี 2018 Git 2.16การเพิ่มโครงสร้างที่เป็นตัวแทนของอัลกอริทึมแฮชการดำเนินการเปลี่ยนไปใช้แฮชใหม่ได้เริ่มขึ้นแล้ว
ดังที่ได้กล่าวข้างต้นกัญชาสนับสนุนใหม่จะSHA-256


การปะทะกัน: 1. ความพยายามในการสร้างการชนไม่ใช่ความบังเอิญ 2. จากรายงาน PDF เต้: รวมคำนวณความพยายามในการใช้จ่ายเทียบเท่ากับ 2 ^ 63.1 SHA-1 กดและใช้เวลาประมาณ6,500 ปี CPU และ GPU 100 ปี 3. ถึงแม้ว่าเราควรดำเนินการต่อจาก MD5 และ SHA-1 แต่โดยทั่วไปแล้วเป็นการปรับสำหรับการใช้งานที่ไม่ซ้ำกัน
zaph

เป็นที่น่าสังเกตว่า WebKit ตรวจสอบ PDF ที่ชนกันเพื่อทดสอบ มันทำลายโครงสร้างพื้นฐานกระจก git-svn ของพวกเขา: bugs.webkit.org/show_bug.cgi?id=168774#c24
dahlbyk

1
@dahlbyk มันน่าสังเกตจริงๆ ... ในที่ฉันบันทึกไว้ในคำตอบ (ลิงค์ที่อยู่เบื้องหลัง "มันมีปัญหาบางอย่างสำหรับgit-svnแม้ว่า" หมายถึงมันถึงแม้ว่าจะเป็นทางอ้อม)
VonC

1
@Mr_and_Mrs_D ไม่มันไม่ได้ล้มเหลวด้วยข้อผิดพลาด กำลังมีการแก้ไขใหญ่ซึ่งจะช่วยอำนวยความสะดวกในการตรวจหาการชน: marc.info/?l=git&m=148987267504882&w=2
VonC

1
@Mr_and_Mrs_D ดูการแก้ไข 4 ในstackoverflow.com/posts/42450327/revisions : มันล้มเหลวทันทีอย่างน้อยเมื่ออัปโหลดไปที่ GitHub
VonC

6

ฉันคิดว่า cryptographers จะเฉลิมฉลอง

อ้างอิงจากบทความ Wikipedia ใน SHA-1 :

ในเดือนกุมภาพันธ์ 2005 มีการโจมตีโดย Xiaoyun Wang, Yiqun Lisa Yin และ Hongbo Yu ถูกประกาศ การโจมตีสามารถค้นหาการชนในเวอร์ชันเต็มของ SHA-1 ซึ่งต้องการการดำเนินการน้อยกว่า 2 ^ 69 (การค้นหาแบบ brute-force ต้องการการดำเนินงาน 2 ^ 80)


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

นี่เป็นเพียงการโจมตีที่พบการชนกันซึ่งหมายความว่าคุณสามารถค้นหาได้yว่าh(x) == h (y) `ซึ่งเป็นภัยคุกคามที่ร้ายแรงสำหรับข้อมูลโดยพลการเช่นใบรับรอง SSL อย่างไรก็ตามสิ่งนี้จะไม่ส่งผลกระทบต่อ Git ซึ่งจะมีความเสี่ยงต่อการโจมตี มีข้อความxคุณสามารถปรับเปลี่ยนไปกับข้อความว่าx' h(x) == h(x')ดังนั้นการโจมตีครั้งนี้จึงไม่ทำให้ Git อ่อนแอลง นอกจากนี้ Git ยังไม่ได้เลือก SHA-1 เพื่อเหตุผลด้านความปลอดภัย
Hauleth

ขณะนี้พบการปะทะกัน - ไม่ใช่แค่การรบกวนที่เกิดขึ้นโดยตรง stackoverflow.com/questions/42433126/…
Willem Hengeveld

2 ^ 69 ประมาณ 600 Exa-Operations แปดปีต่อมา SaturnV ซุปเปอร์คอมพิวเตอร์ของ Nvidia ได้อัปเกรดด้วย A100 สามารถทำได้ 4.6 ExaOPS ดังนั้นจึงสามารถแก้ปัญหานี้ได้ในเวลาเพียง 2 นาทีหรือทำการโจมตีแบบดุเดือดในไม่กี่วัน
qdin

6

มีรูปแบบการโจมตีที่แตกต่างกันหลายแบบสำหรับแฮชเช่น SHA-1 แต่รูปแบบที่มักจะกล่าวถึงคือการค้นหาการชนรวมถึงเครื่องมือHashClashของ Marc Stevens

"ในปี 2012 การโจมตีที่มีประสิทธิภาพมากที่สุดกับ SHA-1 นั้นถือเป็นหนึ่งเดียวโดย Marc Stevens [34] ด้วยค่าใช้จ่ายประมาณ 2.77 ล้านดอลลาร์เพื่อทำลายค่าแฮชเพียงครั้งเดียวด้วยการเช่าพลังงาน CPU จากเซิร์ฟเวอร์คลาวด์"

คุณสามารถบังคับให้มีการชนกับ hit ได้ แต่การทำเช่นนั้นจะไม่เขียนทับวัตถุที่มีอยู่ในที่เก็บอื่น ฉันคิดว่าgit push -f --no-thinจะไม่เขียนทับวัตถุที่มีอยู่ แต่ไม่แน่ใจ 100%

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

ฉันสงสัยว่าหลายสิ่งหลายอย่างที่นักพัฒนาโครงการอาจทำหรืออาจทำลายแฮ็คหลายล้านดอลลาร์โดยบังเอิญ โดยเฉพาะอย่างยิ่งนั่นเป็นเงินจำนวนมากที่ลดลงหากนักพัฒนาบางคนที่คุณไม่ได้แฮ็คเคยทำการทำงานดังกล่าวgit push --no-thinหลังจากทำการแก้ไขไฟล์ที่ได้รับผลกระทบบางครั้งถึงแม้จะไม่ได้ทำ--no-thinอะไรก็ตาม

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