Tiếng Việt

Công cụ dành cho nhà phát triển · Trình tạo UUID

Math.random so với crypto.getRandomValues: Cách thức hoạt động của mỗi trình tạo

· Cách thức hoạt động

uuid mật mã browser-apis

Hai trình tạo ngẫu nhiên đặt cạnh nhau: Math.random dưới dạng máy trạng thái xác định so với crypto.getRandomValues được cung cấp bởi entropy của hệ điều hành
Hình minh họa vector ToolAcre gốc

Cả hai đều trả về các số trông có vẻ ngẫu nhiên, nhưng một số là một máy trạng thái xác định nhỏ và số còn lại được hệ điều hành cung cấp. Đây là những gì mỗi cái thực hiện và tại sao UUID phải sử dụng cái thứ hai.

Đoạn diễn đàn xây dựng UUID từ Math.random — tại sao nó trông ổn và vượt qua mọi bài kiểm tra thông thường

Câu trả lời trên diễn đàn cung cấp một nhà máy UUID nhanh chóng trong tám dòng: cuộn các giá trị từ Math.random và định dạng chúng vào bố cục 8-4-4-4-12. Mã có vẻ ổn và vượt qua mọi bài kiểm tra thông thường. Mỗi mã nhận dạng xuất hiện khác nhau và một mẫu ngắn không hiển thị mẫu trực quan rõ ràng. Đó không phải là thuộc tính mà mã định danh nhạy cảm về bảo mật cần có. JavaScript chỉ định Math.random làm nguồn giả ngẫu nhiên nhưng không yêu cầu khả năng chống lại dự đoán bằng mật mã. Công việc thích hợp của nó bao gồm mô phỏng, trò chơi và xáo trộn. Khi mã định danh có thể ảnh hưởng đến quyền truy cập, phát hiện đối tượng hoặc quyết định đối nghịch khác thì hình thức bên ngoài không còn là bằng chứng nữa. Hợp đồng được ghi lại của trình tạo quan trọng hơn một trang đầu ra trông có vẻ hợp lý.

Bên trong Math.random — một thuật toán giả ngẫu nhiên được tạo mầm với trạng thái bên trong cố định, được thiết kế để đảm bảo tốc độ và mức độ lan truyền thống kê, không bí mật

Vì Math.random không được chỉ định làm trình tạo mật mã nên kết quả đầu ra của nó không được coi là bằng chứng cho thấy các giá trị trong tương lai bị ẩn khỏi người quan sát. crypto.getRandomValues có một hợp đồng nền tảng khác: nó lấp đầy một mảng được nhập số nguyên bằng các giá trị mạnh về mặt mật mã. Đặc tả Web Crypto để lại trình tạo chính xác cho tác nhân người dùng, vì vậy mã ứng dụng không được yêu cầu một thuật toán, kích thước hạt giống hoặc thiết bị entropy cụ thể. ToolAcre chỉ cần ranh giới được hỗ trợ: trình duyệt cung cấp các byte ngẫu nhiên an toàn, JavaScript nhận Uint8Array đã được điền và mã UUID đặt các trường phiên bản và biến thể. Tuyên bố đó vừa hữu ích vừa có tính di động trên các trình duyệt có cách triển khai nội bộ khác nhau.

Tại sao việc quan sát đầu ra có thể tiết lộ trạng thái - tại sao một trạng thái nhỏ có nghĩa là một chuỗi giá trị có thể cho phép ai đó dự đoán trạng thái tiếp theo

Mã ứng dụng nhận các giá trị mạnh về mặt mật mã từ getRandomValues ​​thay vì triển khai hoặc hiển thị trạng thái JavaScript PRNG. Sự khác biệt về bảo mật xuất hiện trong các hệ thống thực. Mã nhận dạng được tạo từ Math.random không phù hợp ở bất kỳ trường hợp dự đoán nào sẽ gây ra hậu quả vì kẻ tấn công có khả năng đọc mạng (hoặc bất kỳ hệ thống nào có thể nhìn thấy UUID trước đó) có thể dự đoán mạng tiếp theo. V4 UUID từ crypto.getRandomValues bản thân nó không phải là mã thông báo xác thực (bạn vẫn cần hết hạn, băm, giới hạn tỷ lệ), nhưng trình tạo được thiết kế để chống lại dự đoán. ToolAcre từ chối tạo số nhận dạng nếu nguồn bảo mật của nó không có, thay vì âm thầm hạ cấp xuống một công thức có thể dự đoán được. Math.random đã xuất hiện với các lỗi phân phối tinh vi trong các công cụ chính. Trình tự đầu ra có thể trông đa dạng mà không mang lại khả năng dự đoán đối nghịch cần thiết cho các vai trò nắm giữ bí mật.

Bên trong crypto.getRandomValues — trình duyệt yêu cầu CSPRNG của hệ điều hành, kết hợp entropy phần cứng và hệ thống và được thiết kế để không thể đoán trước

Các thuật toán dành riêng cho công cụ và hành vi thống kê của chúng có thể thay đổi; cả kiểm tra trực quan lẫn kiểm tra phân phối thông thường đều không nâng cấp Math.random thành nguồn mật mã. Tính toán va chạm cũng giả định kết quả đầu ra độc lập từ không gian đã nêu. Nếu một trình tạo lặp lại trạng thái, được khởi tạo không chính xác hoặc được thay thế bằng một thiết bị xác định cố định thì giả định đó không thành công và công thức không còn mô tả việc triển khai nữa. Cả hai API đều có thể tạo ra các chuỗi trông không đều như nhau. Mô hình mối đe dọa phân tách chúng: các giá trị phải chống lại dự đoán sẽ sử dụng crypto.getRandomValues, trong khi các mô phỏng và xáo trộn không đối nghịch có thể sử dụng Math.random. Sự lựa chọn xuất phát từ kết quả của sự dự đoán, chứ không phải từ dấu câu hoặc sự đa dạng rõ ràng trong một mẫu.

Ví dụ đã hoạt động - tạo cùng số lượng mã nhận dạng với mỗi phương thức và so sánh những gì người quan sát có thể suy ra

Trình tạo ToolAcre UUID chỉ sử dụng crypto.getRandomValues; nó không bao giờ sử dụng Math.random vì chi phí của UUID có thể dự đoán được luôn cao hơn chi phí của một trình tạo chậm hơn một chút. Sự khác biệt về mật mã có thể đo lường được thông qua mô hình mối đe dọa. Kẻ tấn công muốn giả mạo UUID phải đoán trực tiếp mã định danh hoặc phá vỡ trình tạo số ngẫu nhiên. Đoán trực tiếp không phải là sự so sánh mà bài viết này định lượng; kết luận được hỗ trợ là Web Crypto được thiết kế cho tính ngẫu nhiên của mật mã trong khi Math.random thì không. CSPRNG và Math.random thể hiện các hợp đồng khác nhau: hợp đồng trước được thiết kế cho tính ngẫu nhiên nhạy cảm về bảo mật, trong khi hợp đồng sau không mang lại hứa hẹn nào như vậy. Hệ thống sử dụng Math.random cho số nhận dạng đã mất thuộc tính mật mã; tính bảo mật hiện phụ thuộc vào việc giữ bí mật chuỗi UUID được tạo. Chỉ cần một UUID bị rò rỉ, toàn bộ thế hệ tương lai sẽ bị tổn hại.

Lỗi phân phối lịch sử — một lời nhắc nhở rằng các công cụ đã triển khai Math.random triển khai với kết quả đầu ra không đồng đều rõ ràng, được mô tả một cách định tính

Nếu ứng dụng lưu trữ UUID trong nhật ký, cơ sở dữ liệu hoặc lịch sử kiểm soát phiên bản thì việc rò rỉ gần như là không thể tránh khỏi. Thư viện ToolAcre thực thi việc sử dụng crypto.getRandomValues và từ chối tạo UUID nếu bối cảnh bảo mật (HTTPS hoặc localhost) không khả dụng. Quyết định thiết kế này ngăn chặn sự dự phòng thầm lặng cho Math.random vốn gây khó khăn cho nhiều hoạt động triển khai thủ công. Trong Node.js, thư viện sử dụng mô-đun mật mã; trong các trình duyệt, nó sử dụng Web Crypto API. Cả hai đường dẫn được hỗ trợ đều yêu cầu tính ngẫu nhiên mạnh về mặt mật mã từ nền tảng. Việc triển khai không đưa ra yêu cầu về hiệu suất vì động cơ, thiết bị và khối lượng công việc quyết định thời gian; hợp đồng bảo mật là tài sản quyết định đối với số nhận dạng. Lý do tiêu chuẩn ngành được giải quyết dựa trên crypto.getRandomValues là một lịch sử ngắn gọn về việc sử dụng sai mục đích UUID. Các hệ thống ban đầu sử dụng thời gian hệ thống, giao diện mạng và đồng hồ phần cứng để tạo mã định danh.

Điều này không bao gồm điều gì - chất lượng thống kê của một trong hai trình tạo mô phỏng, đây là một câu hỏi khác với tính không thể đoán trước

Các phiên bản UUID dựa trên thời gian, dựa trên nút và ngẫu nhiên giải quyết các vấn đề phân bổ khác nhau; cái này không nên được trình bày dưới dạng sửa chữa tuyến tính cho mọi thiết kế trước đó. Đối với phiên bản 4, RFC 9562 xác định các trường ngẫu nhiên và thảo luận riêng về khả năng không thể đoán được. Do đó, việc di chuyển khỏi Math.random sẽ thay đổi chất lượng của các giá trị mới được tạo mà không thay đổi hình dạng văn bản UUID. Các mã định danh hiện tại vẫn là khóa cơ sở dữ liệu; tái tạo chúng sẽ phá vỡ tài liệu tham khảo. Các giá trị mới có thể sử dụng Web Crypto ngay lập tức, trong khi việc ủy ​​quyền phải tiếp tục coi mọi UUID cũ hoặc mới như một mã định danh thay vì bằng chứng cho phép. Ghi lại mức cắt để người ứng phó sự cố biết trình tạo nào đã tạo ra mỗi quần thể.

Bài học rút ra: chọn trình tạo theo mối đe dọa chứ không phải theo vẻ ngoài — trình tạo ToolAcre UUID chỉ sử dụng CSPRNG trình tạo, không bao giờ Math.random()

Quá trình xác thực phải phân biệt giữa ID cũ (không phù hợp để bảo mật) và ID mới (CSPRNG được hỗ trợ). Tài liệu cần lưu ý quá trình chuyển đổi. Trình tạo ToolAcre chỉ tạo ra crypto.getRandomValues UUID; nó không cố gắng xác thực hoặc tạo lại số nhận dạng từ các nguồn khác. Trình tạo ToolAcre thể hiện phương pháp hay nhất bằng cách từ chối hạ cấp xuống nguồn ngẫu nhiên yếu hơn. Nếu không có crypto.getRandomValues, công cụ sẽ báo lỗi thay vì âm thầm sử dụng Math.random. Nguyên tắc thiết kế này áp dụng cho bất kỳ hệ thống quan trọng về bảo mật nào: thất bại một cách rõ ràng thay vì thành công một cách lặng lẽ với sự đảm bảo về bảo mật yếu. Nhà phát triển nhận thấy "thế hệ UUID không thành công: mật mã API không khả dụng" phải giải quyết vấn đề cơ bản (nâng cấp lên HTTPS, khắc phục bối cảnh bảo mật hoặc cung cấp phương án dự phòng thích hợp). Nhà phát triển âm thầm nhận UUID được tạo từ Math.random không có dấu hiệu nào cho thấy hệ thống bị xâm phạm. Thư viện ToolAcre ưu tiên tính trung thực hơn là sự thuận tiện.