เครื่องมือสำหรับนักพัฒนา · ตัวสร้าง UUID
Math.random กับ crypto.getRandomValues: แต่ละเครื่องกำเนิดไฟฟ้าทำงานอย่างไร
· มันทำงานอย่างไร
uuid การเข้ารหัส เบราว์เซอร์-apis
ตัวเลขส่งคืนทั้งสองที่ดูสุ่ม แต่อันหนึ่งเป็นเครื่องสถานะที่กำหนดขนาดเล็ก และอีกอันถูกป้อนโดยระบบปฏิบัติการ นี่คือสิ่งที่แต่ละคนทำภายใต้ประทุนและเหตุใด UUID จึงต้องใช้อันที่สอง
ตัวอย่างฟอรัมที่สร้าง UUID จาก Math.random — เหตุใดจึงดูดีและผ่านการทดสอบทั่วไปทุกรายการ
คำตอบในฟอรัมเสนอโรงงาน UUID ที่รวดเร็วในแปดบรรทัด: ม้วนค่าจาก Math.random และจัดรูปแบบให้เป็น 8-4-4-4-12 รูปแบบ โค้ดดูดีและผ่านการทดสอบทั่วไปทุกครั้ง ตัวระบุแต่ละตัวจะปรากฏแตกต่างกัน และตัวอย่างสั้นๆ ก็ไม่แสดงรูปแบบภาพที่ชัดเจน นั่นไม่ใช่คุณสมบัติที่ตัวระบุที่ละเอียดอ่อนด้านความปลอดภัยต้องการ JavaScript ระบุ Math.random เป็นแหล่งสุ่มเทียม แต่ไม่ต้องการการต้านทานการเข้ารหัสเพื่อทำนาย งานที่เหมาะสมได้แก่ การจำลอง เกม และการสับเปลี่ยน เมื่อตัวระบุสามารถมีอิทธิพลต่อการเข้าถึง การค้นพบวัตถุ หรือการตัดสินใจของฝ่ายตรงข้าม การปรากฏตัวจะไม่เป็นหลักฐานอีกต่อไป สัญญาที่จัดทำเป็นเอกสารของเครื่องกำเนิดไฟฟ้ามีความสำคัญมากกว่าหน้าผลลัพธ์ที่ดูน่าเชื่อถือ
Inside Math.random — อัลกอริธึมสุ่มเทียมแบบ seeded พร้อมสถานะภายในคงที่ ออกแบบมาเพื่อความเร็วและการแพร่กระจายทางสถิติ ไม่ใช่การรักษาความลับ
เนื่องจาก Math.random ไม่ได้ถูกระบุเป็นตัวสร้างการเข้ารหัส ดังนั้นเอาต์พุตของมันจะต้องไม่ถือเป็นหลักฐานว่าค่าในอนาคตถูกซ่อนจากผู้สังเกตการณ์ crypto.getRandomValues มีสัญญาแพลตฟอร์มที่แตกต่างกัน: โดยเติมอาร์เรย์ที่พิมพ์จำนวนเต็มด้วยค่าที่แข็งแกร่งในการเข้ารหัส ข้อมูลจำเพาะ Web Crypto ปล่อยให้ตัวสร้างที่แน่นอนแก่ตัวแทนผู้ใช้ ดังนั้นโค้ดแอปพลิเคชันไม่ควรอ้างสิทธิ์ในอัลกอริทึม ขนาดเริ่มต้น หรืออุปกรณ์เอนโทรปีโดยเฉพาะ ToolAcre ต้องการเฉพาะขอบเขตที่รองรับ: เบราว์เซอร์ให้ไบต์แบบสุ่มที่ปลอดภัย JavaScript รับ Uint8Array ที่กรอก และโค้ด UUID จะตั้งค่าเวอร์ชันและฟิลด์ตัวแปร ข้อความดังกล่าวมีประโยชน์และพกพาได้บนเบราว์เซอร์ที่มีการใช้งานภายในแตกต่างกัน
เหตุใดการสังเกตผลลัพธ์จึงสามารถเปิดเผยสถานะได้ - การที่สถานะขนาดเล็กหมายถึงการเรียกใช้ค่าสามารถให้ผู้อื่นคาดเดาค่าถัดไปได้อย่างไร
รหัสแอปพลิเคชันได้รับค่าที่มีการเข้ารหัสที่แข็งแกร่งจาก getRandomValues แทนที่จะนำไปใช้หรือเปิดเผยสถานะ JavaScript PRNG ความแตกต่างด้านความปลอดภัยจะปรากฏในระบบจริง ตัวระบุที่สร้างจาก Math.random นั้นไม่เหมาะสมในทุกที่ที่การคาดการณ์จะมีผลกระทบ เนื่องจากผู้โจมตีที่มีความสามารถในการอ่านเครือข่าย (หรือระบบใดๆ ที่มองเห็น UUID ก่อนหน้านี้) สามารถคาดเดาอันถัดไปได้ v4 UUID จาก crypto.getRandomValues ไม่ใช่โทเค็นการตรวจสอบสิทธิ์โดยตัวมันเอง (คุณยังต้องมีการหมดอายุ การแฮช การจำกัดอัตรา) แต่ตัวสร้างได้รับการออกแบบให้ต้านทานการคาดการณ์ ToolAcre ปฏิเสธที่จะสร้างตัวระบุหากไม่มีแหล่งที่มาที่ปลอดภัย แทนที่จะดาวน์เกรดเป็นสูตรที่คาดเดาได้โดยไม่แจ้งให้ทราบ Math.random ได้จัดส่งพร้อมกับข้อบกพร่องในการกระจายเล็กน้อยในเครื่องยนต์หลักๆ ลำดับเอาต์พุตอาจดูแตกต่างออกไปโดยไม่ต้องให้ความไม่แน่นอนของฝ่ายตรงข้ามที่จำเป็นสำหรับบทบาทที่เป็นความลับ
ภายใน crypto.getRandomValues — เบราว์เซอร์ถาม CSPRNG ของระบบปฏิบัติการ ซึ่งผสมฮาร์ดแวร์และเอนโทรปีของระบบ และได้รับการออกแบบมาให้ไม่สามารถคาดเดาได้
อัลกอริธึมเฉพาะเครื่องยนต์และพฤติกรรมทางสถิติสามารถเปลี่ยนแปลงได้ ทั้งการตรวจสอบด้วยภาพหรือการทดสอบการกระจายแบบไม่เป็นทางการจะอัปเกรด Math.random เป็นแหล่งการเข้ารหัส การคำนวณการชนกันยังถือว่าเอาท์พุตเป็นอิสระจากพื้นที่ที่ระบุ ถ้าตัวสร้างเกิดสถานะซ้ำ ถูก seed ไม่ถูกต้อง หรือถูกแทนที่ด้วยฟิกซ์เจอร์ที่กำหนด สมมติฐานนั้นจะล้มเหลว และสูตรไม่ได้อธิบายการใช้งานอีกต่อไป API ทั้งสองสามารถสร้างสตริงที่ดูผิดปกติเท่ากันได้ โมเดลภัยคุกคามแยกพวกมันออกจากกัน: ค่าที่ต้องต้านทานการคาดการณ์จะใช้ crypto.getRandomValues ในขณะที่การจำลองและการสับเปลี่ยนที่ไม่ใช่ฝ่ายตรงข้ามอาจใช้ Math.random ตัวเลือกจะเป็นไปตามผลลัพธ์ของการทำนาย ไม่ใช่จากเครื่องหมายวรรคตอนหรือความหลากหลายที่ชัดเจนในกลุ่มตัวอย่าง
ตัวอย่างการทำงาน — สร้างตัวระบุจำนวนเท่ากันในแต่ละวิธี และเปรียบเทียบสิ่งที่ผู้สังเกตการณ์สามารถอนุมานได้
ตัวสร้าง ToolAcre UUID ใช้ crypto.getRandomValues โดยเฉพาะ; มันไม่เคยใช้ Math.random เพราะต้นทุนของ UUID ที่คาดเดาได้นั้นสูงกว่าต้นทุนของตัวสร้างที่ช้ากว่าเล็กน้อยเสมอ ความแตกต่างในการเข้ารหัสสามารถวัดได้ผ่านโมเดลภัยคุกคาม ผู้โจมตีที่ต้องการปลอมแปลง UUID จะต้องเดาตัวระบุโดยตรงหรือทำลายตัวสร้างตัวเลขสุ่ม การคาดเดาโดยตรงไม่ใช่การเปรียบเทียบเชิงปริมาณในบทความนี้ ข้อสรุปที่ได้รับการสนับสนุนคือ Web Crypto มีไว้สำหรับการเข้ารหัสแบบสุ่มในขณะที่ Math.random ไม่ใช่ CSPRNG และ Math.random เปิดเผยสัญญาที่แตกต่างกัน โดยแบบแรกได้รับการออกแบบสำหรับการสุ่มที่คำนึงถึงความปลอดภัย ในขณะที่แบบหลังไม่มีสัญญาดังกล่าว ระบบที่ใช้ Math.random สำหรับตัวระบุได้สูญเสียคุณสมบัติการเข้ารหัส การรักษาความปลอดภัยตอนนี้ขึ้นอยู่กับการรักษาลำดับของ UUID ที่สร้างขึ้นเป็นความลับ หาก UUID รั่วแม้แต่ครั้งเดียว คนรุ่นอนาคตทั้งหมดก็จะถูกโจมตี
ข้อบกพร่องในการกระจายในอดีต — เป็นการเตือนใจว่าเอ็นจิ้นได้ส่งมอบการใช้งาน Math.random โดยมีเอาต์พุตที่ไม่สม่ำเสมออย่างเห็นได้ชัด ตามที่อธิบายในเชิงคุณภาพ
หากแอปพลิเคชันจัดเก็บ UUID ไว้ในบันทึก ฐานข้อมูล หรือประวัติการควบคุมเวอร์ชัน การรั่วไหลนี้แทบจะหลีกเลี่ยงไม่ได้ ไลบรารี ToolAcre บังคับใช้ crypto.getRandomValues และปฏิเสธที่จะสร้าง UUID หากไม่มีบริบทที่ปลอดภัย (HTTPS หรือ localhost) การตัดสินใจออกแบบนี้ป้องกันการย้อนกลับแบบเงียบๆ ไปที่ Math.random ซึ่งรบกวนการใช้งานด้วยตนเองจำนวนมาก ใน Node.js ไลบรารีใช้โมดูล crypto ในเบราว์เซอร์จะใช้ Web Crypto API เส้นทางที่รองรับทั้งสองร้องขอการสุ่มที่แข็งแกร่งในการเข้ารหัสจากแพลตฟอร์ม การใช้งานไม่มีการอ้างสิทธิ์ประสิทธิภาพเนื่องจากกลไก อุปกรณ์ และปริมาณงานกำหนดเวลา สัญญาการรักษาความปลอดภัยเป็นทรัพย์สินในการตัดสินใจสำหรับตัวระบุ เหตุใดมาตรฐานอุตสาหกรรมจึงตัดสินที่ crypto.getRandomValues จึงมีประวัติโดยย่อของการใช้ UUID ในทางที่ผิด ระบบในยุคแรกใช้เวลาของระบบ อินเทอร์เฟซเครือข่าย และนาฬิกาฮาร์ดแวร์เพื่อสร้างตัวระบุ
สิ่งนี้ไม่ครอบคลุม - คุณภาพทางสถิติของเครื่องกำเนิดทั้งสองสำหรับการจำลอง ซึ่งเป็นคำถามที่แตกต่างจากความคาดเดาไม่ได้
เวอร์ชัน UUID ตามเวลา อิงตามโหนด และแบบสุ่ม แก้ปัญหาการจัดสรรที่แตกต่างกัน ไม่ควรนำเสนอเป็นการซ่อมแซมเชิงเส้นสำหรับทุกการออกแบบก่อนหน้านี้ สำหรับเวอร์ชัน 4 RFC 9562 จะกำหนดฟิลด์แบบสุ่มและอภิปรายเรื่องที่ไม่สามารถคาดเดาแยกกันได้ การย้ายออกจาก Math.random จึงเปลี่ยนคุณภาพของค่าที่สร้างขึ้นใหม่โดยไม่เปลี่ยนรูปร่าง UUID ที่เป็นข้อความ ตัวระบุที่มีอยู่ยังคงเป็นคีย์ฐานข้อมูล การสร้างพวกมันขึ้นมาใหม่จะทำลายการอ้างอิง ค่าใหม่สามารถใช้ Web Crypto ได้ทันที ในขณะที่การให้สิทธิ์จะต้องถือว่า UUID เก่าหรือใหม่ทุกรายการเป็นตัวระบุ แทนที่จะเป็นหลักฐานการอนุญาต บันทึกการตัดยอดเพื่อให้ผู้เผชิญเหตุทราบว่าเครื่องกำเนิดใดที่ผลิตประชากรแต่ละราย
ประเด็นสำคัญ: เลือกตัวสร้างตามภัยคุกคาม ไม่ใช่ตามลักษณะที่ปรากฏ — ตัวสร้าง ToolAcre UUID ใช้ CSPRNG โดยเฉพาะ ไม่ใช้ Math.random()
การตรวจสอบควรแยกความแตกต่างระหว่างรหัสเดิม (ไม่เหมาะสำหรับการรักษาความลับ) และรหัสใหม่ (CSPRNG-backed) เอกสารประกอบควรสังเกตการเปลี่ยนแปลง ตัวสร้าง ToolAcre สร้างเฉพาะ crypto.getRandomValues UUID เท่านั้น มันไม่ได้พยายามตรวจสอบหรือสร้างตัวระบุจากแหล่งอื่น ตัวสร้าง ToolAcre สาธิตแนวทางปฏิบัติที่ดีที่สุดโดยปฏิเสธที่จะดาวน์เกรดเป็นแหล่งสุ่มที่อ่อนแอกว่า หากไม่มี crypto.getRandomValues เครื่องมือจะรายงานข้อผิดพลาดแทนที่จะใช้ Math.random โดยไม่ต้องแจ้งให้ทราบ หลักการออกแบบนี้ใช้กับระบบที่มีความสำคัญต่อความปลอดภัย: ล้มเหลวเสียงดัง แทนที่จะประสบความสำเร็จอย่างเงียบๆ โดยมีการรับประกันความปลอดภัยที่อ่อนแอ นักพัฒนาที่เห็น "UUID การสร้างล้มเหลว: crypto API ไม่พร้อมใช้งาน" จะต้องแก้ไขปัญหาที่สำคัญ (อัปเกรดเป็น HTTPS แก้ไขบริบทที่ปลอดภัย หรือจัดเตรียมทางเลือกที่เหมาะสม) นักพัฒนาที่ได้รับ UUID ที่สร้างจาก Math.random โดยไม่แจ้งให้ทราบ ไม่มีข้อบ่งชี้ว่าระบบถูกบุกรุก ห้องสมุด ToolAcre ให้ความสำคัญกับความซื่อสัตย์มากกว่าความสะดวกสบาย