Chúng ta hãy chơi một số bài xì phé trên máy tính, chỉ có bạn, tôi và một máy chủ mà cả hai chúng tôi đều tin tưởng. Máy chủ sử dụng bộ tạo số giả ngẫu nhiên, được khởi tạo với hạt 32 bit ngay trước khi chúng tôi chơi. Vì vậy, có khoảng bốn tỷ sàn có thể.
Tôi có năm thẻ trong tay - dường như chúng tôi không chơi Texas Hold 'Em. Giả sử các thẻ được xử lý một cho tôi, một cho bạn, một cho tôi, một cho bạn, v.v. Vì vậy, tôi có các thẻ đầu tiên, thứ ba, thứ năm, thứ bảy và thứ chín trong bộ bài.
Trước đó, tôi đã chạy trình tạo số giả ngẫu nhiên bốn tỷ lần, một lần với mỗi hạt giống và viết ra thẻ đầu tiên được tạo cho mỗi thẻ vào cơ sở dữ liệu. Giả sử thẻ đầu tiên của tôi là nữ hoàng thuổng. Điều đó chỉ hiển thị một là thẻ đầu tiên trong một trong số 52 sàn có thể, vì vậy chúng tôi đã cắt giảm các sàn có thể từ bốn tỷ xuống còn khoảng 80 triệu.
Giả sử thẻ thứ hai của tôi là ba trái tim. Bây giờ tôi chạy RNG 80 triệu lần nữa bằng cách sử dụng 80 triệu hạt giống tạo ra nữ hoàng thuổng làm số đầu tiên. Điều này làm tôi mất vài giây. Tôi viết ra tất cả các cỗ bài tạo ra ba trái tim là lá bài thứ ba - lá bài thứ hai trong tay tôi. Đó chỉ là khoảng 2% số sàn, vì vậy bây giờ chúng tôi giảm xuống còn 2 triệu sàn.
Giả sử thẻ thứ ba trong tay tôi là 7 câu lạc bộ. Tôi có một cơ sở dữ liệu gồm 2 triệu hạt giống xử lý hai thẻ của mình; Tôi điều hành RNG của mình thêm 2 triệu lần nữa để tìm 2% số sàn tạo ra 7 câu lạc bộ làm thẻ thứ ba, và chúng tôi chỉ còn 40 nghìn sàn.
Bạn thấy điều này diễn ra như thế nào. Tôi chạy RNG 40000 lần nữa để tìm tất cả các hạt giống tạo ra thẻ thứ tư của mình và điều đó khiến chúng tôi giảm xuống 800 sàn, và sau đó chạy thêm 800 lần nữa để có ~ 20 hạt giống tạo ra thẻ thứ năm của tôi, và bây giờ tôi chỉ tạo ra hai mươi bộ bài đó và tôi biết rằng bạn có một trong hai mươi bàn tay có thể. Hơn nữa, tôi có một ý tưởng rất hay về những gì tôi sẽ vẽ tiếp theo.
Bây giờ bạn có thấy tại sao sự ngẫu nhiên thực sự là quan trọng? Cách bạn mô tả nó, bạn nghĩ rằng phân phối là quan trọng, nhưng phân phối không phải là thứ tạo nên một quá trình ngẫu nhiên. Không thể đoán trước là những gì làm cho một quá trình ngẫu nhiên.
CẬP NHẬT
Dựa trên các nhận xét (hiện đã bị xóa do tính chất không liên quan của họ), ít nhất 0,3% những người đã đọc điều này bị nhầm lẫn theo quan điểm của tôi. Khi mọi người tranh luận với những điểm tôi chưa đưa ra, hoặc tệ hơn, tranh luận về những điểm mà tôi đã đưa ra với giả định rằng tôi không tạo ra chúng, thì tôi biết rằng tôi cần phải giải thích rõ ràng và cẩn thận hơn.
Dường như có sự nhầm lẫn đặc biệt xung quanh việc phân phối từ vì vậy tôi muốn gọi ra cách sử dụng một cách cẩn thận.
Các câu hỏi trong tầm tay là:
- Làm thế nào để số giả ngẫu nhiên và số thực sự ngẫu nhiên khác nhau?
- Tại sao sự khác biệt quan trọng?
- Sự khác biệt có liên quan gì đến việc phân phối đầu ra của PRNG không?
Hãy bắt đầu bằng cách xem xét cách hoàn hảo để tạo ra một cỗ bài ngẫu nhiên để chơi bài xì phé. Sau đó, chúng ta sẽ thấy các kỹ thuật khác để tạo sàn khác nhau như thế nào và liệu có thể tận dụng sự khác biệt đó hay không.
Hãy bắt đầu bằng cách giả sử rằng chúng ta có một hộp ma thuật được dán nhãn TRNG
. Khi đầu vào của nó, chúng tôi cung cấp cho nó một số nguyên n lớn hơn hoặc bằng một, và vì đầu ra của nó, nó cung cấp cho chúng tôi một số thực sự ngẫu nhiên giữa một và n, bao gồm. Đầu ra của hộp là hoàn toàn không thể đoán trước (khi được đưa ra một số khác một) và bất kỳ số nào giữa một và n cũng có khả năng như một số khác; đó là để nói rằng phân phối là thống nhất . .
Chúng tôi bắt đầu với một bộ bài không xáo trộn. Chúng tôi yêu cầu hộp cho một số từ một đến 52 - nghĩa là , TRNG(52)
. Bất kể số nào nó trả lại, chúng tôi sẽ đếm được rất nhiều thẻ từ bộ bài đã sắp xếp của chúng tôi và xóa thẻ đó. Nó trở thành lá bài đầu tiên trong bộ bài xáo trộn. Sau đó, chúng tôi yêu cầu TRNG(51)
và làm tương tự để chọn thẻ thứ hai, và như vậy.
Một cách khác để xem xét nó là: có 52! = 52 x 51 x 50 ... x 2 x 1 sàn có thể, xấp xỉ 2 226 . Chúng tôi đã chọn một trong số họ một cách ngẫu nhiên.
Bây giờ chúng tôi giải quyết các thẻ. Khi tôi nhìn vào thẻ của mình, tôi không biết bạn có thẻ gì. (Ngoài thực tế rõ ràng là bạn không có bất kỳ thẻ nào tôi có.) Chúng có thể là bất kỳ thẻ nào, với xác suất như nhau.
Vì vậy, hãy để tôi chắc chắn rằng tôi giải thích điều này rõ ràng. Chúng tôi có phân phối thống nhất của từng đầu ra riêng lẻ của TRNG(n)
; mỗi người chọn một số từ 1 đến n với xác suất 1 / n. Ngoài ra, kết quả của quá trình này là chúng tôi đã chọn một trong số 52! sàn có thể với một xác suất 1/52 !, nên sự phân bố trên tập các sàn có thể là cũng thống nhất.
Được rồi
Bây giờ hãy giả sử rằng chúng ta có một hộp ma thuật ít hơn, được dán nhãn PRNG
. Trước khi bạn có thể sử dụng nó, nó phải được gieo bằng số không dấu 32 bit.
ASIDE: Tại sao 32 ? Nó không thể được gieo bằng số 64 hoặc 256 hoặc 10000 bit? Chắc chắn rồi. Nhưng (1) trong thực tế, hầu hết các PRNG ngoài luồng đều được gieo số 32 bit và (2) nếu bạn có 10000 bit ngẫu nhiên để tạo hạt giống thì tại sao bạn lại sử dụng PRNG? Bạn đã có một nguồn 10000 bit ngẫu nhiên!
Dù sao, trở lại cách PRNG hoạt động: sau khi nó được gieo, bạn có thể sử dụng nó giống như cách bạn sử dụng TRNG
. Đó là, bạn truyền cho nó một số, n, và nó cung cấp cho bạn một số từ 1 đến n, bao gồm. Hơn nữa, sự phân phối của đầu ra đó ít nhiều đồng đều . Đó là, khi chúng tôi yêu cầu PRNG
một số từ 1 đến 6, chúng tôi nhận được 1, 2, 3, 4, 5 hoặc 6 mỗi khoảng một phần sáu thời gian, bất kể hạt giống là gì.
Tôi muốn nhấn mạnh điểm này nhiều lần vì nó có vẻ là một trong những người bình luận khó hiểu. Việc phân phối PRNG được thống nhất theo ít nhất hai cách. Đầu tiên, giả sử chúng ta chọn bất kỳ hạt giống cụ thể. Chúng tôi hy vọng rằng chuỗi PRNG(6), PRNG(6), PRNG(6)...
một triệu lần sẽ tạo ra sự phân bố số lượng đồng đều từ 1 đến 6. Và thứ hai, nếu chúng tôi chọn một triệu hạt giống khác nhau và được gọi PRNG(6)
một lần cho mỗi hạt giống, một lần nữa chúng tôi sẽ mong đợi sự phân bố số lượng đồng đều từ 1 đến 6. Tính đồng nhất của PRNG trên một trong hai hoạt động này không liên quan đến cuộc tấn công mà tôi đang mô tả .
Quá trình này được cho là giả ngẫu nhiên vì hành vi của hộp thực sự hoàn toàn mang tính quyết định; nó chọn một trong 2 32 hành vi có thể dựa trên hạt giống. Nghĩa là, một khi nó được gieo hạt, PRNG(6), PRNG(6), PRNG(6), ...
tạo ra một chuỗi các số có phân bố đồng đều, nhưng chuỗi đó hoàn toàn được xác định bởi hạt giống. Đối với một chuỗi các cuộc gọi nhất định, giả sử PRNG (52), PRNG (51) ... và chỉ có 2 32 chuỗi có thể. Hạt giống về cơ bản chọn cái mà chúng ta nhận được.
Để tạo một cỗ máy chủ bây giờ tạo một hạt giống. (Làm thế nào? Chúng ta sẽ quay trở lại điểm đó.) Sau đó, họ gọi PRNG(52)
, PRNG(51)
và cứ thế tạo ra cỗ bài, tương tự như trước đây.
Hệ thống này dễ bị tấn công mà tôi mô tả. Để tấn công máy chủ, trước tiên, hãy chọn bản sao của hộp bằng 0 và yêu cầu PRNG(52)
và viết nó xuống. Sau đó, chúng tôi tái lập hạt giống với 1, yêu cầu PRNG(52)
và viết nó xuống, tất cả các cách lên đến 2 32 -1.
Bây giờ, máy chủ poker đang sử dụng PRNG để tạo các sàn phải tạo ra một hạt giống nào đó. Không quan trọng làm thế nào họ làm như vậy. Họ có thể gọi TRNG(2^32)
để có được một hạt giống thực sự ngẫu nhiên. Hoặc họ có thể lấy thời gian hiện tại làm hạt giống, điều này hầu như không ngẫu nhiên; Tôi biết mấy giờ nó cũng nhiều như bạn. Điểm tấn công của tôi là nó không quan trọng, vì tôi có cơ sở dữ liệu của mình . Khi tôi nhìn thấy thẻ đầu tiên của mình, tôi có thể loại bỏ 98% số hạt giống có thể. Khi tôi nhìn thấy thẻ thứ hai của mình, tôi có thể loại bỏ thêm 98%, và cứ thế, cho đến cuối cùng tôi có thể nhận được một số hạt giống có thể, và biết rất có khả năng những gì trong tay bạn.
Bây giờ, một lần nữa, tôi muốn nhấn mạnh rằng giả định ở đây là nếu chúng ta gọi PRNG(6)
một triệu lần, chúng ta sẽ nhận được mỗi số khoảng một phần sáu thời gian . Phân phối đó là (ít nhiều) đồng nhất và nếu tính đồng nhất của phân phối đó là tất cả những gì bạn quan tâm , thì tốt thôi. Điểm của câu hỏi là có những thứ khác PRNG(6)
mà chúng ta quan tâm không? và câu trả lời là có . Chúng tôi quan tâm về sự khó lường là tốt.
Một cách khác để xem xét vấn đề là mặc dù việc phân phối một triệu cuộc gọi PRNG(6)
có thể ổn, vì PRNG chỉ chọn từ 2 32 hành vi có thể, nhưng nó không thể tạo ra mọi sàn có thể. Nó chỉ có thể tạo 2 32 trong số 2 226 sàn có thể; một phần rất nhỏ Vì vậy, việc phân phối trên tập hợp tất cả các sàn là rất xấu. Nhưng một lần nữa, cuộc tấn công cơ bản ở đây dựa trên việc chúng ta có thể dự đoán thành công hành vi trong quá khứ và tương lai PRNG
từ một mẫu nhỏ của sản phẩm đầu ra.
Hãy để tôi nói điều này một hoặc ba lần để đảm bảo điều này chìm vào. Có ba bản phân phối ở đây. Đầu tiên, phân phối của quá trình tạo ra hạt giống 32 bit ngẫu nhiên. Điều đó có thể là hoàn toàn ngẫu nhiên, không thể đoán trước và thống nhất và cuộc tấn công sẽ vẫn hoạt động . Thứ hai, việc phân phối một triệu cuộc gọi đến PRNG(6)
. Điều đó có thể hoàn toàn thống nhất và cuộc tấn công vẫn sẽ hoạt động. Thứ ba, việc phân phối các sàn được chọn theo quy trình giả ngẫu nhiên mà tôi đã mô tả. Sự phân phối đó cực kỳ nghèo nàn; chỉ một phần rất nhỏ của các sàn IRL có thể có thể được chọn. Cuộc tấn công phụ thuộc vào khả năng dự đoán hành vi của PRNG dựa trên kiến thức một phần về đầu ra của nó .
ASIDE: Cuộc tấn công này yêu cầu kẻ tấn công biết hoặc có thể đoán thuật toán chính xác được sử dụng bởi PRNG là gì. Cho dù đó là thực tế hay không là một câu hỏi mở. Tuy nhiên, khi thiết kế một hệ thống bảo mật, bạn phải thiết kế nó để an toàn trước các cuộc tấn công ngay cả khi kẻ tấn công biết tất cả các thuật toán trong chương trình . Nói cách khác: phần của hệ thống bảo mật phải giữ bí mật để hệ thống được bảo mật được gọi là "khóa". Nếu hệ thống của bạn phụ thuộc vào bảo mật của nó đối với các thuật toán bạn sử dụng là bí mật thì khóa của bạn chứa các thuật toán đó . Đó là một vị trí cực kỳ yếu để được vào!
Tiến lên.
Bây giờ hãy giả sử rằng chúng ta có một hộp ma thuật thứ ba được dán nhãn CPRNG
. Nó là một phiên bản sức mạnh của tiền điện tử PRNG
. Nó lấy một hạt giống 256 bit thay vì hạt giống 32 bit. Nó chia sẻ với PRNG
tài sản mà hạt giống chọn từ một trong 2 256 hành vi có thể. Và giống như các máy khác của chúng tôi, nó có một số lượng lớn các cuộc gọi để CPRNG(n)
tạo ra sự phân phối kết quả thống nhất giữa 1 và n: mỗi lần xảy ra 1 / n thời gian. Chúng ta có thể chạy cuộc tấn công của chúng tôi chống lại nó?
Cuộc tấn công ban đầu của chúng tôi yêu cầu chúng tôi lưu trữ 2 32 ánh xạ từ hạt giống đến PRNG(52)
. Nhưng 2 256 là một con số lớn hơn nhiều; nó là hoàn toàn không thể chạy được CPRNG(52)
nhiều lần và lưu trữ kết quả.
Nhưng giả sử có một số cách khác để lấy giá trị CPRNG(52)
và từ đó suy ra một thực tế về hạt giống? Chúng tôi đã khá ngu ngốc cho đến nay, chỉ cần vũ phu buộc tất cả các kết hợp có thể. Chúng ta có thể nhìn vào bên trong chiếc hộp ma thuật, tìm ra cách nó hoạt động và suy luận sự thật về hạt giống dựa trên đầu ra không?
Không. Các chi tiết quá phức tạp để giải thích, nhưng CPRNG được thiết kế khéo léo để không thể suy ra bất kỳ sự thật hữu ích nào về hạt giống từ đầu ra đầu tiên của CPRNG(52)
hoặc từ bất kỳ tập hợp con nào của đầu ra, bất kể lớn đến đâu .
OK, vì vậy bây giờ hãy giả sử máy chủ đang sử dụng CPRNG
để tạo các sàn. Nó cần một hạt giống 256-bit. Làm thế nào để nó chọn hạt giống đó? Nếu nó chọn bất kỳ giá trị nào mà kẻ tấn công có thể dự đoán thì đột nhiên cuộc tấn công trở nên khả thi trở lại . Nếu chúng ta có thể xác định rằng trong số 256 hạt giống có thể, chỉ có bốn tỷ trong số chúng có khả năng được chọn bởi máy chủ, thì chúng ta đã quay trở lại hoạt động . Chúng ta có thể gắn kết cuộc tấn công này một lần nữa, chỉ chú ý đến số lượng nhỏ hạt giống có thể được tạo ra.
Do đó, máy chủ nên thực hiện công việc để đảm bảo rằng số 256 bit được phân phối đồng đều - nghĩa là, mỗi hạt giống có thể được chọn với xác suất 1/2 256 . Về cơ bản, máy chủ sẽ được gọi TRNG(2^256)-1
để tạo hạt giống cho CPRNG
.
Điều gì sẽ xảy ra nếu tôi có thể hack máy chủ và ngó vào nó để xem hạt giống nào được chọn? Trong trường hợp đó, kẻ tấn công biết quá khứ và tương lai hoàn toàn của CPRNG . Tác giả của máy chủ cần phải bảo vệ chống lại cuộc tấn công này! (Tất nhiên nếu tôi có thể thực hiện thành công cuộc tấn công này thì có lẽ tôi cũng có thể chuyển tiền trực tiếp vào tài khoản ngân hàng của mình, vì vậy có lẽ điều đó không thú vị. Điểm là: hạt giống phải là một bí mật khó đoán và số 256-bit thực sự ngẫu nhiên rất khó đoán.)
Quay trở lại quan điểm trước đây của tôi về phòng thủ chuyên sâu: hạt giống 256 bit là chìa khóa cho hệ thống bảo mật này. Ý tưởng của CPRNG là hệ thống được bảo mật miễn là khóa được bảo mật ; ngay cả khi mọi sự thật khác về thuật toán được biết đến, miễn là bạn có thể giữ bí mật chính, thẻ của đối thủ là không thể đoán trước.
OK, vì vậy, hạt giống nên được phân phối đồng đều và bí mật bởi vì nếu không, chúng ta có thể thực hiện một cuộc tấn công. Chúng tôi có giả định rằng việc phân phối đầu ra CPRNG(n)
là thống nhất. Điều gì về phân phối trên tập hợp của tất cả các sàn có thể?
Bạn có thể nói: có 2 256 trình tự có thể xuất ra bởi CPRNG, nhưng chỉ có 2 226 sàn có thể. Do đó, có nhiều trình tự có thể hơn các sàn, vì vậy chúng tôi ổn; mọi sàn IRL có thể hiện có (với xác suất cao) có thể có trong hệ thống này. Và đó là một cuộc tranh luận tốt ngoại trừ ...
2 226 chỉ là xấp xỉ 52!. Chia nó ra. 2 256/52 ! không thể là một con số nguyên vẹn vì một điều, 52! chia hết cho 3 nhưng không có lũy thừa hai là! Vì đây không phải là toàn bộ số bây giờ, chúng ta có tình huống tất cả các sàn đều có thể , nhưng một số sàn có nhiều khả năng hơn các sàn khác .
Nếu điều đó không rõ ràng, hãy xem xét tình huống với số lượng nhỏ hơn. Giả sử chúng ta có ba thẻ, A, B và C. Giả sử chúng ta sử dụng PRNG với hạt 8 bit, do đó có 256 hạt giống có thể. Có 256 đầu ra có thể PRNG(3)
phụ thuộc vào hạt giống; không có cách nào để có một phần ba trong số họ là A, một phần ba trong số họ là B và một phần ba trong số họ là C vì 256 không chia hết cho 3. Có một sự thiên vị nhỏ đối với một trong số họ.
Tương tự, 52 không chia đều cho 2 256 , do đó phải có một số sai lệch đối với một số thẻ làm thẻ đầu tiên được chọn và sai lệch so với các thẻ khác.
Trong hệ thống ban đầu của chúng tôi với hạt giống 32 bit, có sự thiên vị lớn và phần lớn các sàn có thể không bao giờ được sản xuất. Trong hệ thống này, tất cả các sàn có thể được sản xuất, nhưng việc phân phối các sàn vẫn còn thiếu sót . Một số sàn rất có khả năng hơn một số khác.
Bây giờ câu hỏi là: chúng ta có một cuộc tấn công dựa trên lỗ hổng này không? và câu trả lời là trong thực tế, có lẽ là không . CPRNG được thiết kế sao cho nếu hạt giống thực sự ngẫu nhiên thì không thể tính toán được sự khác biệt giữa CPRNG
và TRNG
.
OK, vậy hãy tổng hợp lại.
Làm thế nào để số giả ngẫu nhiên và số thực sự ngẫu nhiên khác nhau?
Họ khác nhau về mức độ dự đoán mà họ thể hiện.
- Con số ngẫu nhiên thực sự là không thể dự đoán.
- Tất cả các số giả ngẫu nhiên đều có thể dự đoán được nếu hạt giống có thể được xác định hoặc đoán.
Tại sao sự khác biệt quan trọng?
Bởi vì có những ứng dụng mà tính bảo mật của hệ thống phụ thuộc vào sự không thể đoán trước .
- Nếu TRNG được sử dụng để chọn từng thẻ thì hệ thống không khả dụng.
- Nếu CPRNG được sử dụng để chọn từng thẻ thì hệ thống sẽ an toàn nếu hạt giống không thể đoán trước và không xác định.
- Nếu một PRNG thông thường có không gian hạt nhỏ được sử dụng thì hệ thống sẽ không an toàn bất kể hạt giống đó là không thể đoán trước hay không biết; một không gian hạt giống đủ nhỏ dễ bị tấn công bằng vũ lực của loại tôi đã mô tả.
Sự khác biệt có liên quan gì đến việc phân phối đầu ra của PRNG không?
Tính thống nhất của phân phối hoặc thiếu đó cho các cuộc gọi cá nhân để RNG(n)
không liên quan đến các vụ tấn công tôi đã mô tả.
Như chúng ta đã thấy, cả a PRNG
và CPRNG
tạo ra các phân phối kém về xác suất chọn bất kỳ sàn riêng lẻ nào trong tất cả các sàn có thể. Điều PRNG
tồi tệ hơn đáng kể, nhưng cả hai đều có vấn đề.
Một câu hỏi nữa:
Nếu TRNG tốt hơn nhiều so với CPRNG, điều này lại tốt hơn nhiều so với PRNG, tại sao mọi người sử dụng CPRNG hoặc PRNG?
Hai lý do.
Thứ nhất: chi phí. TRNG là đắt tiền . Tạo số thực sự ngẫu nhiên là khó khăn. CPRNG cho kết quả tốt cho nhiều cuộc gọi tùy ý chỉ với một cuộc gọi đến TRNG cho hạt giống. Mặt trái của khóa học là bạn phải giữ bí mật về hạt giống đó .
Thứ hai: đôi khi chúng tôi muốn dự đoán và tất cả những gì chúng tôi quan tâm là phân phối tốt. Nếu bạn đang tạo dữ liệu "ngẫu nhiên" làm đầu vào chương trình cho bộ kiểm tra và nó xuất hiện một lỗi, thì thật tuyệt khi chạy lại bộ kiểm tra lại tạo ra lỗi một lần nữa!
Tôi hy vọng rằng bây giờ rõ ràng hơn nhiều.
Cuối cùng, nếu bạn thích điều này thì bạn có thể thích đọc thêm về chủ đề ngẫu nhiên và hoán vị: