เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ · SHA เครื่องคำนวณแฮช
การระบุที่อยู่เนื้อหา: Git, Docker และ npm ใช้ SHA แยกแยะเป็นชื่ออย่างไร
· พื้นหลัง
sha-256 docker การเข้ารหัส นักพัฒนาเวิร์กโฟลว์
การคอมมิต Git การย่อยอิมเมจคอนเทนเนอร์ และสตริงความสมบูรณ์ของไฟล์ล็อคล้วนมีแนวคิดเดียวกัน นั่นคือการตั้งชื่อข้อมูลด้วยแฮช โพสต์นี้จะอธิบายการจัดการกับเนื้อหาและสิ่งที่แต่ละระบบนิเวศได้รับจากเนื้อหา
sha256: ใน docker pull ของคุณ — สตริงนั้นคืออะไร และเหตุใดจึงไม่เปลี่ยนแปลงสำหรับรูปภาพเดียวกัน
ระบบควบคุมเวอร์ชัน รันไทม์ของคอนเทนเนอร์ และตัวจัดการแพ็คเกจล้วนใช้แนวคิดการตั้งชื่อเดียวกัน: ไฟล์หรือคอลเลกชั่นของไบต์ตั้งชื่อตามไดเจสต์ SHA ใน Git ตัวระบุ 40 อักขระ SHA-1 ของคอมมิต (หรือ 64 อักขระ SHA-256 ในที่เก็บข้อมูลสมัยใหม่) จะถูกคำนวณจากเนื้อหาของคอมมิต เช่น แผนผัง ผู้เขียน การประทับเวลา และข้อความ เปลี่ยนไบต์เดียวและ SHA เปลี่ยนแปลง ใน Docker แต่ละเลเยอร์ย่อยจะเป็นแฮช SHA-256 ของเนื้อหาของเลเยอร์ และการแยกย่อยรูปภาพจะคำนวณจากไฟล์ Manifest ในเวลา npm และตัวจัดการแพ็คเกจอื่นๆ ฟิลด์ความสมบูรณ์จะจัดเก็บ SHA-512 การแยกย่อยของ tarball เพื่อตรวจสอบการดาวน์โหลด การกำหนดที่อยู่เนื้อหาหมายความว่าชื่อจะขึ้นอยู่กับไบต์เท่านั้น ไม่ใช่ในฐานข้อมูลกลางหรือการประทับเวลา
ประโยชน์คือความไม่เปลี่ยนรูปภายในแต่ละระบบ คอมไพล์คอมมิต SHA-256:abc... จะอ้างถึงแผนผังและข้อความเดียวกันเสมอ เนื่องจากแฮชเป็นตัวกำหนดข้อมูลประจำตัว หากมีคนอ้างว่ามีคอมมิตที่แตกต่างกันด้วย SHA เดียวกัน พวกเขากำลังอ้างว่าไบต์เดียวกันสร้างแฮชที่แตกต่างกันสองอัน ซึ่งจะทำให้การเข้ารหัสเสียหาย การขจัดข้อมูลซ้ำซ้อนกลายเป็นไปโดยอัตโนมัติ: ไฟล์สองไฟล์ที่มีไบต์เหมือนกันจะสร้างข้อมูลย่อยที่เหมือนกัน ดังนั้นระบบจัดเก็บข้อมูลจึงสามารถจัดเก็บไบต์ได้หนึ่งครั้งและอ้างอิงถึงสองครั้ง การตรวจสอบความสมบูรณ์กลายเป็นเรื่องง่ายเหมือนกับการคำนวณการย่อยใหม่และการเปรียบเทียบ: หากมีการแก้ไขไบต์ระหว่างทางหรือขณะพัก การสรุปจะไม่ตรงกันอีกต่อไป
การตั้งชื่อข้อมูลตามแฮช — แนวคิดในการกำหนดที่อยู่เนื้อหา และเหตุใดจึงทำให้การขจัดข้อมูลซ้ำซ้อนและความสมบูรณ์ฟรี
Git จัดเก็บอ็อบเจ็กต์ต่างๆ เช่น คอมมิต ต้นไม้ blobs และแท็ก โดยคีย์โดยสรุป SHA คำสั่ง `git cat-file` รับ ID อ็อบเจ็กต์และดึงข้อมูลไบต์ ที่เก็บอ็อบเจ็กต์มีการกำหนดแอดเดรสของเนื้อหา: คุณร้องขอโดยการสรุป ไม่ใช่ตามตำแหน่งหรือตามชื่อ เมื่อคุณโคลนพื้นที่เก็บข้อมูล git จะตรวจสอบแต่ละอ็อบเจ็กต์ด้วยการคำนวณการแยกย่อยอีกครั้ง และตรวจสอบกับการแยกย่อยที่อัดแน่นอยู่ในการถ่ายโอน การเปลี่ยนจาก SHA-1 เป็น SHA-256 เป็นแบบค่อยเป็นค่อยไป ที่เก็บข้อมูลสามารถรองรับทั้งความเข้ากันได้ รูปแบบบนดิสก์จะจัดเก็บประเภทอ็อบเจ็กต์ ขนาด และไบต์ที่บีบอัด การสรุปข้อมูลจะถูกคำนวณผ่านรูปแบบที่ไม่มีการบีบอัดตามรูปแบบบัญญัติ
พื้นที่เก็บข้อมูล Git สมัยใหม่สามารถใช้ SHA-256 ได้ และการเปลี่ยนแปลงยังคงดำเนินไปเนื่องจาก SHA-1 การชนกันนั้นใช้งานได้จริง (สาธิตใน 2017 และปรับปรุงใน 2020) คอมมิตในพื้นที่เก็บข้อมูลโดยใช้ SHA-256 มีตัวระบุฐานสิบหก 64 อักขระ แทนที่จะเป็น 40 คำสั่ง `git hash-object` คำนวณ SHA ของ blob (เนื้อหาไฟล์) โดยไม่ต้องจัดเก็บ `git commit-tree` คำนวณ SHA ของโครงสร้างต้นไม้และข้อความ การดำเนินการทั้งสองถูกกำหนดไว้: ไบต์เดียวกันจะสร้างข้อมูลย่อยที่เหมือนกันเสมอ นี่คือวิธีที่ GitHub และ Forge อื่นๆ สามารถแสดงการคอมมิต SHA อย่างสม่ำเสมอ โดยจะคำนวณการย่อยแบบเดียวกันกับที่คำนวณโคลนของผู้เขียน
Git ใช้ออบเจ็กต์ที่ระบุถึงเนื้อหา และเครื่องมือนี้สามารถสร้างการแยกย่อยข้อความได้ รายละเอียดการย้ายข้อมูลต้องใช้แหล่งที่มาเฉพาะของ Git
อิมเมจ Docker ถูกสร้างขึ้นในเลเยอร์ โดยแต่ละเลเยอร์เป็นระบบไฟล์เดลต้า (เปลี่ยนแปลงจากเลเยอร์ก่อนหน้า) OCI Image Spec กำหนดวิธีการคำนวณส่วนย่อยของเลเยอร์และส่วนย่อยของไฟล์ Manifest การแยกย่อยของเลเยอร์คือ SHA-256 ของไฟล์ tar ที่ถูกบีบอัดซึ่งมีไฟล์เลเยอร์ ไฟล์ Manifest คือเอกสาร JSON ที่แสดงรายการเลเยอร์ ข้อมูลสรุป และข้อมูลเมตา การแยกย่อยรูปภาพคือ SHA-256 ของไฟล์ Manifest JSON เอง เมื่อคุณดึงรูปภาพโดยใช้แท็ก เช่น `latest` รีจิสตรีจะค้นหาแท็กและส่งกลับรายการสรุป จากนั้นคุณสามารถดึงข้อมูลแบบแยกย่อยได้โดยตรง เพื่อให้มั่นใจว่าคุณได้รับไบต์เดียวกันทุกประการ—ทุกเลเยอร์และข้อมูลเมตา—ทุกครั้ง
คำสั่ง `docker inspect` บนอิมเมจในเครื่องจะแสดงข้อมูลสรุป การเรียกใช้อิมเมจเดียวกันจากแท็กเดียวกันบนเครื่องสองเครื่องจะสร้างไดเจสต์เดียวกัน หากรีจิสทรียังคงเก็บแท็กนั้นซึ่งชี้ไปยังไฟล์ Manifest เดียวกัน การระบุที่อยู่เนื้อหาทำให้ห่วงโซ่อุปทานของรูปภาพสามารถตรวจสอบได้: ไปป์ไลน์ CI/CD สามารถยืนยันได้ว่ารูปภาพที่ปรับใช้นั้นตรงกับการแยกย่อยในบันทึกบิลด์ และเครื่องสแกนความปลอดภัยสามารถรายงานรูปภาพทั้งหมดที่ทราบว่ามีช่องโหว่เฉพาะโดยการแยกย่อย แทนที่จะใช้แท็ก ซึ่งสามารถเคลื่อนย้ายได้
คอนเทนเนอร์ — OCI แสดงรายการและการแยกย่อยเลเยอร์ และสาเหตุที่แท็กสามารถย้ายได้ แต่การแยกย่อยไม่สามารถทำได้
ผู้จัดการแพ็คเกจใช้ไดเจสต์เพื่อตรวจสอบการดาวน์โหลดจากการปลอมแปลงหรือความเสียหาย ในเวลา npm ไฟล์ `package-lock.json` จะรวมฟิลด์ `integrity` สำหรับการขึ้นต่อกันแต่ละรายการ โดยมีแฮช (ปกติคือ SHA-512) และการเข้ารหัส (โดยปกติจะเป็น base64) เมื่อ npm ดาวน์โหลด tarball มันจะคำนวณแฮชใหม่และเปรียบเทียบ หากแฮชไม่ตรงกัน การติดตั้งจะล้มเหลว Go ใช้ไฟล์ `go.sum` ที่มีโครงสร้างคล้ายกัน: เส้นทางโมดูล เวอร์ชัน และ SHA-256 ของแหล่งที่มาของโมดูล สินค้าใช้เช็คซัมใน `Cargo.lock` หลักการเหมือนกัน: การแยกย่อยจะถูกคำนวณหนึ่งครั้งเมื่อมีการแก้ไขการขึ้นต่อกันในครั้งแรก และตรวจสอบในการติดตั้งครั้งต่อไปทุกครั้ง
การตรวจสอบความสมบูรณ์ไม่จำเป็นต้องอัปโหลดแพ็คเกจไปยังหน่วยงานที่ลงนามหรือจัดเก็บลายเซ็นแยกต่างหาก สรุปคือการตรวจสอบความสมบูรณ์ เพื่อความมั่นใจสูงสุด โปรเจ็กต์ใช้ `go.sum` ซึ่งลงนามโดยระบบความโปร่งใสของโปรเจ็กต์ Go หรือความสมบูรณ์ npm รวมกับการตรวจสอบอื่นๆ แต่กรณีพื้นฐานนั้นง่าย: ผู้เผยแพร่คำนวณไดเจสต์หนึ่งครั้ง บันทึกลงในไฟล์ล็อค และเครื่องมือในฝั่งผู้บริโภคจะตรวจสอบว่าไบต์ที่ดาวน์โหลดตรงกัน
การเข้ารหัสความสมบูรณ์ของแพ็คเกจจะแตกต่างกันไป เฉพาะเอาต์พุต SHA ที่รองรับของเครื่องคิดเลขนี้เท่านั้นที่ได้รับการยืนยันที่นี่
ไบต์เดียวกันผ่านอัลกอริธึมเดียวกันจะสร้างไดเจสต์เดียวกันเสมอ ไม่ว่าไบต์จะมาจากไหนก็ตาม คอมมิตในเครื่องของนักพัฒนาจะสร้าง SHA-256 เดียวกันกับระบบ CI/CD ที่ตรวจสอบการแก้ไขเดียวกันจากที่เก็บเดียวกัน ความสามารถในการทำซ้ำนี้เป็นสาเหตุที่ทำให้การกำหนดที่อยู่เนื้อหาใช้งานได้: คุณสามารถตรวจสอบอาร์ติแฟกต์ได้โดยไม่ต้องเชื่อถือกลไกการนำส่ง การสรุปข้อมูลกลายเป็นข้อผูกมัดในการเข้ารหัส: การเปลี่ยนแปลงแม้แต่หนึ่งไบต์จะทำให้การย่อยนั้นไม่ถูกต้อง
การกระจายข้อมูลสรุปแยกกัน (ก่อนแจกจ่ายสิ่งประดิษฐ์) จะป้องกันการดัดแปลงบนเครื่องบิน หน้าเว็บที่เผยแพร่ก่อนเผยแพร่สามารถแสดง "คาดหวัง SHA-256:abc..." จากนั้นผู้ใช้สามารถยืนยันการดาวน์โหลดได้ คอมไพล์คอมมิตที่เผยแพร่ในพื้นที่เก็บข้อมูลสาธารณะคือความมุ่งมั่นต่อไบต์ การย่อยจะพิสูจน์มัน
ตัวอย่างการทำงาน - ติดตามหนึ่งหยดจากไบต์เพื่อแยกแยะชื่อที่เครื่องมือใช้
ระบบที่ต่างกันเข้ารหัสการย่อยต่างกัน Git ใช้เลขฐานสิบหกตัวพิมพ์เล็กตามค่าเริ่มต้น (40 หรือ 64 อักขระฐานสิบหก) นักเทียบท่าใช้รูปแบบ `sha256:` ตามด้วยเลขฐานสิบหก npm และ Go ใช้ base64 ในช่องความสมบูรณ์ ไบต์จะเหมือนกัน มีเพียงการเป็นตัวแทนเท่านั้นที่แตกต่างกัน การสรุป SHA-256 ส่วน "abc" จะเหมือนกันเสมอ 256 bits แต่คุณอาจเห็นว่าเป็นสตริงฐานสิบหกอักขระ 64 สตริงอักขระ base64 44 อักขระ หรือป้ายกำกับเช่น `sha256:` ตามด้วยอย่างใดอย่างหนึ่ง การแปลงระหว่างการเข้ารหัสนั้นไม่มีการสูญเสีย การย่อยเป็นค่าเดียวกันในทุกการนำเสนอ
การทำความเข้าใจการเข้ารหัสมีความสำคัญเมื่อเปรียบเทียบไดเจสต์ระหว่างเครื่องมือต่างๆ หาก Git พิมพ์ข้อมูลสรุปแบบเลขฐานสิบหกและเครื่องมือแสดง base64 คุณต้องแปลงการแสดงหนึ่งไปเป็นอีกการแสดงหนึ่งเพื่อตรวจสอบว่าตรงกัน ToolAcreของ SHA เครื่องคำนวณแฮชจะแสดงทั้งเลขฐานสิบหกและฐาน 64 สำหรับทุกการแยกย่อย ทำให้ง่ายต่อการแปลงหรืออ้างอิงโยงกับระบบอื่น
สิ่งนี้ไม่ครอบคลุม — การเข้ารหัสเฉพาะที่แต่ละเครื่องมือใช้ (ฐานสิบหกกับฐาน 64) ซึ่งครอบคลุมอยู่ในโพสต์แยกต่างหาก
การกำหนดที่อยู่เนื้อหาไม่ได้เฉพาะเจาะจงกับการเข้ารหัส แม้ว่าแฮชการเข้ารหัสจะทำให้มีความปลอดภัยก็ตาม การตรวจสอบ CRC32 ยังเป็นข้อมูลที่อยู่เนื้อหาด้วย แต่การชนกันของ CRC32 เป็นเรื่องปกติ และการชนกันสามารถเกิดขึ้นได้ พื้นที่เก็บข้อมูลนี้ไม่ได้ทำเครื่องหมาย SHA-256 ว่าใช้งานไม่ได้ ในขณะที่ CRC32 ไม่ได้ถูกเสนอให้เป็นความสมบูรณ์ของฝ่ายตรงข้ามแบบดั้งเดิม การเลือกอัลกอริธึมแฮชมีความสำคัญต่อความปลอดภัย: SHA-256 เป็นมาตรฐานสมัยใหม่สำหรับระบบที่ต้องการการปกป้องความสมบูรณ์ต่อฝ่ายตรงข้าม SHA-1 เป็นแบบเดิมเท่านั้น (Git และโปรแกรมอื่นๆ กำลังย้ายออกไป) การเลือกอัลกอริธึมที่เหมาะสมเป็นการตัดสินใจแยกต่างหากจากการเลือกการกำหนดที่อยู่เนื้อหาเป็นรูปแบบการตั้งชื่อ
การระบุเนื้อหารวมกับแฮชการเข้ารหัสเป็นรากฐานของความสมบูรณ์ของห่วงโซ่อุปทานในซอฟต์แวร์สมัยใหม่ ทุกแพ็คเกจที่คุณติดตั้ง ทุกคอนเทนเนอร์ที่คุณเรียกใช้ และทุกคอมมิตที่คุณเช็คเอาท์สามารถตรวจสอบได้ว่าเป็นไบต์ที่ผู้เผยแพร่ดั้งเดิมตั้งใจ โดยไม่ต้องอาศัยการถ่ายโอนที่ปลอดภัย (แม้ว่าการถ่ายโอนที่ปลอดภัยยังคงเป็นแนวทางปฏิบัติที่ดี)
ประเด็นสำคัญ: แฮชคือตัวตน — เครื่องคำนวณแฮช ToolAcre SHA ช่วยให้คุณสามารถคำนวณการแยกย่อยแบบเดียวกันที่ระบบเหล่านี้พึ่งพา
การกำหนดที่อยู่เนื้อหาไม่ขึ้นอยู่กับการเข้ารหัส ตำแหน่งที่จัดเก็บ หรือกลไกการถ่ายโอน ไบต์เดียวกันจะสร้างไดเจสต์เดียวกันไม่ว่าจะจัดเก็บไว้ในเครื่อง ใน CDN ในรีจิสทรี หรือส่งผ่าน HTTP หรือ HTTPS แบบปลอดภัย การแยกย่อยคือความมุ่งมั่นในการเข้ารหัสลับต่อไบต์ และการตรวจสอบว่าต้องใช้เพียงไบต์และอัลกอริธึมเท่านั้น ไม่ใช่บริการภายนอกใดๆ นี่คือสาเหตุที่การกำหนดที่อยู่เนื้อหาเปิดใช้งานการตรวจสอบแบบออฟไลน์: คุณสามารถดาวน์โหลดไฟล์ผ่านช่องทางที่ไม่น่าเชื่อถือ ตรวจสอบสรุป และทราบว่าไบต์เป็นของแท้หรือไม่
เครื่องคำนวณแฮช ToolAcre SHA ช่วยให้คุณสามารถคำนวณข้อมูลย่อยแบบเดียวกับที่ระบบเหล่านี้พึ่งพา วางสตริงหรือดูไฟล์ เรียกใช้เครื่องคิดเลขและดู SHA-256, SHA-384 และ SHA-512 แยกย่อยที่ Docker, Git, npm และเครื่องมืออื่นๆ ใช้งานภายใน เปรียบเทียบการแยกย่อยที่คำนวณของคุณกับข้อมูลจากแหล่งดั้งเดิมเพื่อตรวจสอบว่าไบต์ไม่ได้รับการแก้ไข เครื่องคิดเลขแฮชข้อความ UTF-8 ที่คุณวาง ไม่มีการแฮชไฟล์หรือเนื้อหาคีย์ ดังนั้นขอบเขตระหว่างสิ่งที่แฮชได้ (การป้อนข้อความ) และสิ่งที่แฮชไม่ได้ (ไฟล์ไบนารี่ คีย์การเข้ารหัสในรูปแบบที่เข้ารหัส) จึงมีความชัดเจนและบันทึกไว้