Làm thế nào để đối phó với một trình tạo SecureRandom chậm?


165

Nếu bạn muốn một số ngẫu nhiên mạnh về mật mã trong Java, bạn sử dụng SecureRandom. Thật không may, SecureRandomcó thể rất chậm. Nếu nó sử dụng /dev/randomtrên Linux, nó có thể chặn việc chờ đủ entropy để xây dựng. Làm thế nào để bạn tránh bị phạt hiệu suất?

Có ai đã sử dụng Toán học không phổ biến như một giải pháp cho vấn đề này chưa?

Bất cứ ai cũng có thể xác nhận rằng vấn đề hiệu năng này đã được giải quyết trong JDK 6?


Có vẻ như điều này có liên quan đến sự chậm chạp của SecureRandom.generateSeed () . Có một khiếm khuyết bị từ chối giải thích sự chậm chạp và cách giải quyết: JDK-6521844: SecureRandom bị treo trên Hệ thống Linux
AlikElzin-kilaka

Kiểm tra / dev / urandom (không phải / dev / ngẫu nhiên) .. Hãy xem xét chỉ nhận một hạt giống tạo số ngẫu nhiên từ urandom nếu có vấn đề chặn.
jcalfee314

Câu trả lời:


79

Nếu bạn muốn dữ liệu ngẫu nhiên thực sự, thì thật không may, bạn phải chờ nó. Điều này bao gồm hạt giống cho một SecureRandomPRNG. Toán học không phổ biến không thể thu thập dữ liệu ngẫu nhiên thực sự nhanh hơn SecureRandom, mặc dù nó có thể kết nối với internet để tải xuống dữ liệu hạt giống từ một trang web cụ thể. Tôi đoán là điều này khó có thể nhanh hơn /dev/randomnơi có sẵn.

Nếu bạn muốn PRNG, hãy làm một cái gì đó như thế này:

SecureRandom.getInstance("SHA1PRNG");

Chuỗi nào được hỗ trợ tùy thuộc vào SecureRandomnhà cung cấp SPI, nhưng bạn có thể liệt kê chúng bằng cách sử dụng Security.getProviders()Provider.getService().

Sun rất thích SHA1PRNG, vì vậy nó có sẵn rộng rãi. Nó không đặc biệt nhanh khi PRNG đi, nhưng PRNG sẽ chỉ là những con số khủng khiếp, không chặn được phép đo entropy vật lý.

Ngoại lệ là nếu bạn không gọi setSeed()trước khi nhận dữ liệu, thì PRNG sẽ tự khởi động lại ngay lần đầu tiên bạn gọi next()hoặc nextBytes(). Nó thường sẽ làm điều này bằng cách sử dụng một lượng khá nhỏ dữ liệu ngẫu nhiên thực sự từ hệ thống. Cuộc gọi này có thể chặn, nhưng sẽ làm cho nguồn số ngẫu nhiên của bạn an toàn hơn nhiều so với bất kỳ biến thể nào của "băm thời gian hiện tại cùng với PID, thêm 27 và hy vọng điều tốt nhất". Tuy nhiên, nếu tất cả những gì bạn cần là số ngẫu nhiên cho một trò chơi hoặc nếu bạn muốn luồng được lặp lại trong tương lai bằng cách sử dụng cùng một hạt giống cho mục đích thử nghiệm, thì một hạt giống không an toàn vẫn hữu ích.


Toán học không phổ biến chỉ tải xuống dữ liệu từ Internet để gieo hạt, nó không trả về dữ liệu ngẫu nhiên đó khi tạo số ngẫu nhiên.
Dan Dyer

Tương tự với SecureRandom - / dev / urandom chỉ dành cho seeding.
AviD

Vâng. Khi người hỏi nói "nếu bạn muốn có một số ngẫu nhiên, bạn sử dụng SecureRandom - điều này có thể chậm", tôi nghĩ có lẽ anh ta đang sử dụng getSeed cho mọi thứ và rút cạn hồ bơi entropy của mình. Cách khắc phục không phải là để có được JDK 6, đó là sử dụng SecureRandom theo cách nó dự định ;-)
Steve Jessop

@Dan Dyer - Tôi đã sửa nhận xét của mình về Toán học không phổ biến. Tôi đã xem trang của bạn, vì vậy tôi biết rằng bằng "số ngẫu nhiên" tôi có nghĩa là "cho hạt giống của nó" chứ không phải là "để trả lại cho người dùng". Nhưng bạn hoàn toàn đúng, đó không phải là những gì tôi đã nói ...
Steve Jessop

"nó có sẵn rộng rãi". Nó không được bao gồm với mọi JDK tuân thủ? Nó nằm trong danh sách các tên tiêu chuẩn bảo mật java ... ( docs.oracle.com/javase/8/docs/technotes/guides/security/ trộm )
Sean Reilly

176

Bạn sẽ có thể chọn nhóm / dev / urandom nhanh hơn nhưng hơi kém an toàn trên Linux bằng cách sử dụng:

-Djava.security.egd=file:/dev/urandom

Tuy nhiên, điều này không hoạt động với Java 5 trở lên ( Java Bug 6202721 ). Công việc được đề xuất là sử dụng:

-Djava.security.egd=file:/dev/./urandom

(lưu ý thêm /./)


24
Lưu ý rằng báo cáo Lỗi Java cho biết "Không phải là lỗi". Nói cách khác, mặc dù là mặc định /dev/urandom, Sun coi đây là một chuỗi ma thuật và sử dụng /dev/randommọi cách, vì vậy bạn phải giả mạo nó. Khi nào một file:URL không phải là một file:URL? Bất cứ khi nào Sun quyết định thì không :-(
Jim Garrison

6
Chỉ cần dành một đống thời gian để điều tra việc này, có vẻ như cài đặt bình thường, ngay cả khi file:/dev/urandomđược đặt trong -Djava.security.egdhoặc trong securerandom.sourcetệp java.security, /dev/random/vẫn được đọc bất cứ khi nào SecureRandom.getSeed()(hoặc setSeed()được gọi). Cách giải quyết với file:/dev/./urandomkết quả hoàn toàn không đọc /dev/random(được xác nhận bằng strace)
matt b

7
/dev/urandomkhông an toàn hơn so với /dev/randomkhi được triển khai với CSPRNG hiện đại: en.wikipedia.org/wiki//dev/random#FreeBSD
lapo

Tôi nghĩ nỗi sợ chính /dev/urandom/là điều gì sẽ xảy ra nếu bạn sử dụng nó để tạo ra những bí mật trên phần cứng mới, điều này có thể ở trong một trạng thái khá dễ đoán. /dev/urandom/sẽ không chặn entropy mặc dù đó là một trường hợp mà bạn nên làm. Tình hình thậm chí còn tồi tệ hơn nếu bí mật vẫn còn tồn tại, giống như nếu điều đầu tiên thiết bị của bạn thực hiện trong lần khởi động đầu tiên là tạo ra một cặp khóa công khai. Bên ngoài những tình huống đáng sợ đó, một điều tốt /dev/urandomvẫn tốt hơn là sử dụng các SecureRandomthuật toán thông thường .
Steve Jessop

1
Cái nào đúng ? -Djava.security.egd = file: / dev /./ urandom hoặc tệp: /// dev / urandom @mattb
Aarish Ramesh

35

Trên Linux, việc triển khai mặc định SecureRandomNativePRNG(mã nguồn ở đây ), có xu hướng rất chậm. Trên Windows, mặc định là SHA1PRNG, như những người khác đã chỉ ra, bạn cũng có thể sử dụng trên Linux nếu bạn chỉ định rõ ràng.

NativePRNGkhác với SHA1PRNGvà Uncommons Toán AESCounterRNG ở chỗ nó liên tục nhận được entropy từ hệ điều hành (bằng cách đọc từ /dev/urandom). Các PRNG khác không thu được bất kỳ entropy bổ sung nào sau khi gieo hạt.

AESC gặpRNG nhanh hơn khoảng 10 lần SHA1PRNG, mà IIRC tự nó nhanh hơn hai hoặc ba lần NativePRNG.

Nếu bạn cần một PRNG nhanh hơn để có được entropy sau khi khởi tạo, hãy xem bạn có thể tìm thấy một triển khai Java của Fortuna không . PRNG cốt lõi của việc triển khai Fortuna giống hệt với AESC gặpRNG được sử dụng, nhưng cũng có một hệ thống tinh vi của việc gộp chung entropy và tạo lại tự động.


Liên kết này không hoạt động. unommons-maths.dev.java.net/nonav/api/org/uncommons/maths/ mẹo . Có nơi nào tôi có thể thấy điều này?
UVM

@Unni Chỉ cần cập nhật liên kết. Xin lưu ý rằng các khiếu nại về hiệu suất tôi đưa ra trong câu trả lời này có thể không còn hiệu lực nữa. Tôi nghĩ mọi thứ có thể đã tốt hơn trong các phiên bản Java gần đây và có thể có sự khác biệt về hiệu năng giữa các nền tảng (ví dụ Windows so với Liux).
Dan Dyer

Tôi vừa chạy một ví dụ về SecureRandom với MessageDigest và thực hiện mã hóa nó. Toàn bộ hoạt động trong PC 7 của tôi mất 33 mili giây. Tôi đã sử dụng SHA1PRNG.SecureRandom prng = SecureRandom.getInstance ("SHA1PRNG"); Chuỗi RandomNum = new Integer (prng.nextInt ()) .toString (); MessageDigest sha = MessageDigest.getInstance ("SHA-1"); result = sha.digest (RandomNum.getBytes ()); str = hexEncode (kết quả);
UVM

24

Nhiều bản phân phối Linux (chủ yếu dựa trên Debian) định cấu hình OpenJDK để sử dụng /dev/randomcho entropy.

/dev/random là theo định nghĩa chậm (và thậm chí có thể chặn).

Từ đây bạn có hai tùy chọn về cách bỏ chặn nó:

  1. Cải thiện entropy, hoặc
  2. Giảm yêu cầu ngẫu nhiên.

Lựa chọn 1, Cải thiện entropy

Để có được thành entropy hơn /dev/random, hãy thử các haveged daemon. Đó là một trình nền liên tục thu thập entropy HAVEGE và cũng hoạt động trong môi trường ảo hóa vì nó không yêu cầu bất kỳ phần cứng đặc biệt nào, chỉ có CPU và đồng hồ.

Trên Ubuntu / Debian:

apt-get install haveged
update-rc.d haveged defaults
service haveged start

Trên RHEL / CentOS:

yum install haveged
systemctl enable haveged
systemctl start haveged

Tùy chọn 2. Giảm yêu cầu ngẫu nhiên

Nếu vì một lý do nào đó, giải pháp trên không giúp ích được gì hoặc bạn không quan tâm đến tính ngẫu nhiên mạnh về mật mã, bạn có thể chuyển sang /dev/urandomthay thế, điều này được đảm bảo không chặn.

Để thực hiện nó trên toàn cầu, hãy chỉnh sửa tệp jre/lib/security/java.securitytrong cài đặt Java mặc định của bạn để sử dụng /dev/urandom(do một lỗi khác mà nó cần phải được chỉ định là /dev/./urandom).

Như thế này:

#securerandom.source=file:/dev/random
securerandom.source=file:/dev/./urandom

Sau đó, bạn sẽ không bao giờ phải chỉ định nó trên dòng lệnh.


Lưu ý: Nếu bạn làm mật mã, bạn cần entropy tốt. Trường hợp điển hình - vấn đề PRNG android làm giảm tính bảo mật của ví Bitcoin.


Nâng cao câu trả lời của bạn, nhưng " /dev/randomtheo định nghĩa là chậm (và thậm chí có thể chặn)" là sai; nó hoàn toàn phụ thuộc vào cấu hình hệ thống. Các máy mới hơn có thể có RNG nhanh trong CPU có thể được sử dụng và các máy BSD thường có cùng triển khai cho /dev/random/devl/urandom. Tuy nhiên, có lẽ bạn không nên dựa vào /dev/random việc nhanh chóng, nhất thiết phải. Trên máy ảo, bạn có thể muốn cài đặt bộ công cụ máy khách trên máy khách VM để có thể sử dụng RNG của hệ điều hành máy chủ.
Maarten Bodewes

17

Tôi gặp vấn đề tương tự với các cuộc gọi để SecureRandomchặn khoảng 25 giây một lần trên máy chủ Debian không đầu. Tôi đã cài đặt havegedtrình nền để đảm bảo /dev/randomluôn được cập nhật, trên các máy chủ không đầu, bạn cần một cái gì đó như thế này để tạo ra entropy cần thiết. Các cuộc gọi của tôi đến SecureRandombây giờ có lẽ mất một phần nghìn giây.


4
cài đặt apt-get đã được cài đặt sau đó update-rc.d đã mặc định mặc định
Rod Lima

11

Nếu bạn muốn sự ngẫu nhiên thực sự "mạnh về mật mã", thì bạn cần một nguồn entropy mạnh. /dev/randomchậm vì phải chờ các sự kiện hệ thống thu thập entropy (đọc đĩa, gói mạng, di chuyển chuột, nhấn phím, v.v.).

Một giải pháp nhanh hơn là một bộ tạo số ngẫu nhiên phần cứng. Bạn có thể đã có sẵn một bo mạch chủ; kiểm tra tài liệu hw_random để biết hướng dẫn về việc tìm ra nếu bạn có nó và cách sử dụng nó. Gói công cụ rng bao gồm một trình nền sẽ cung cấp entropy được tạo bằng phần cứng /dev/random.

Nếu một HRNG không có sẵn trên hệ thống của bạn và bạn sẵn sàng hy sinh sức mạnh của entropy để thực hiện, bạn sẽ muốn tạo ra một PRNG tốt với dữ liệu từ đó /dev/randomvà để PRNG thực hiện phần lớn công việc. Có một số PRNG được NIST phê duyệt được liệt kê trong SP800-90 rất dễ thực hiện.


Điểm tốt, nhưng mã của tôi là một phần của ứng dụng thương mại. Tôi không có quyền kiểm soát môi trường máy chủ. Tôi nghĩ rằng các máy chủ mục tiêu luôn không có chuột và bàn phím và hoàn toàn dựa vào I / O của đĩa và mạng cho entropy, đây có lẽ là vấn đề gốc.
David G

3
Tôi phát hiện ra rằng / dev / ngẫu nhiên phụ thuộc vào các sự kiện hệ thống, vì vậy như một cách giải quyết tạm thời, tôi chỉ di chuyển chuột qua lại trong khi thử nghiệm của mình chạy ....
David K

Đó là trung tâm 82802 cho chipset i820 rất chậm (RIP). Tôi ngạc nhiên bạn có thể thu thập bất cứ điều gì hữu ích từ nó. Tôi nghĩ rằng tôi đã dành nhiều thời gian hơn để chặn nó hơn là thu thập các octet.
jww

6

Sử dụng Java 8, tôi thấy rằng trên cuộc gọi Linux SecureRandom.getInstanceStrong()sẽ cung cấp cho tôi NativePRNGBlockingthuật toán. Điều này thường sẽ chặn trong nhiều giây để tạo ra một vài byte muối.

Tôi chuyển sang yêu cầu rõ ràng NativePRNGNonBlockingthay vào đó, và như mong đợi từ cái tên, nó không còn bị chặn nữa. Tôi không biết ý nghĩa bảo mật của việc này là gì. Có lẽ phiên bản không chặn không thể đảm bảo lượng entropy được sử dụng.

Cập nhật : Ok, tôi tìm thấy lời giải thích tuyệt vời này .

Tóm lại, để tránh bị chặn, hãy sử dụng new SecureRandom(). Điều này sử dụng /dev/urandom, không chặn và về cơ bản là an toàn như /dev/random. Từ bài đăng: "Lần duy nhất bạn muốn gọi / dev / ngẫu nhiên là khi máy khởi động lần đầu và entropy chưa được tích lũy".

SecureRandom.getInstanceStrong() mang lại cho bạn RNG mạnh nhất tuyệt đối, nhưng nó chỉ an toàn khi sử dụng trong các tình huống mà một loạt các chặn sẽ không ảnh hưởng đến bạn.


1
Tôi chỉ cho phép getInstanceStrong() các khóa dài hạn, chẳng hạn như các khóa cho chứng chỉ TLS. Và thậm chí sau đó tôi thà sử dụng new SecureRandom()hoặc một trình tạo cặp khóa tuân thủ mật khẩu hoặc trình tạo số ngẫu nhiên. Vì vậy, có, điều này cung cấp một câu trả lời, nếu /dev/urandom không chặn: cuối cùng thì nó vẫn dựa vào entropy hệ thống; nhưng đó là lời khuyên rất tốt nói chung . Nếu /dev/urandomcác khối bạn có thể phải sửa nguồn của sự cố thay vì ứng dụng Java của bạn.
Maarten Bodewes

5

Có một công cụ (ít nhất là trên Ubuntu) sẽ cung cấp tính ngẫu nhiên nhân tạo vào hệ thống của bạn. Lệnh này chỉ đơn giản là:

rngd -r /dev/urandom

và bạn có thể cần một sudo ở phía trước. Nếu bạn không có gói công cụ rng, bạn sẽ cần cài đặt nó. Tôi đã thử điều này, và nó chắc chắn đã giúp tôi!

Nguồn: matt vs thế giới


2
Điều này hơi nguy hiểm vì nó vô hiệu hóa hoàn toàn ước tính mức entropy của nhân Linux, toàn hệ thống. Tôi nghĩ cho mục đích thử nghiệm (đọc: Jenkins chạy thử nghiệm của ứng dụng) bằng cách sử dụng /dev/./urandom là tốt, nhưng trong sản xuất, thì không.
mirabilos

Đây thực sự là giải pháp duy nhất hiệu quả với tôi. Tôi đã gặp phải một vấn đề entropy không đủ entropy khi xây dựng một dự án Android với Gradle trên Jenkins CI và việc truyền tham số cho bản dựng không giúp ích được gì.
Slav

Tôi đã phải kết hợp sudo rngd -r /dev/urandomvới sudo apt install rng-toolstrong xenial
MrMesees

5

Tôi phải đối mặt với cùng một vấn đề . Sau một số Google với các cụm từ tìm kiếm phù hợp, tôi đã xem qua bài viết hay này trên DigitalOcean .

hasged là một giải pháp tiềm năng mà không ảnh hưởng đến an ninh.

Tôi chỉ đơn thuần trích dẫn phần có liên quan từ bài viết ở đây.

Dựa trên nguyên tắc HAVEGE và trước đây dựa trên thư viện liên kết của nó, đã cho phép tạo tính ngẫu nhiên dựa trên các biến thể trong thời gian thực thi mã trên bộ xử lý. Vì gần như không thể để một đoạn mã có cùng thời gian thực thi, ngay cả trong cùng một môi trường trên cùng một phần cứng, thời gian chạy một hoặc nhiều chương trình phải phù hợp để tạo nguồn ngẫu nhiên. Việc triển khai đã tạo hạt giống nguồn ngẫu nhiên của hệ thống của bạn (thường là / dev / ngẫu nhiên) bằng cách sử dụng các khác biệt trong bộ đếm dấu thời gian của bộ xử lý (TSC) sau khi thực hiện lặp lại nhiều lần

Cách cài đặt

Thực hiện theo các bước trong bài viết này. https://www.digitalocean.com/community/tutorials/how-to-setup-additable-entropy-for-cloud-servers-USE-haveged

Tôi đã đăng nó ở đây


5

Vấn đề bạn tham khảo /dev/randomkhông phải ở SecureRandomthuật toán, mà là nguồn ngẫu nhiên mà nó sử dụng. Hai là trực giao. Bạn nên tìm ra cái nào trong hai cái đang làm bạn chậm lại.

Trang Toán học không phổ biến mà bạn liên kết rõ ràng đề cập rằng chúng không giải quyết nguồn gốc của sự ngẫu nhiên.

Bạn có thể thử các nhà cung cấp JCE khác nhau, chẳng hạn như BouncyCastle, để xem việc triển khai của họ SecureRandomcó nhanh hơn không.

Một tìm kiếm ngắn gọn cũng cho thấy các bản vá Linux thay thế việc triển khai mặc định bằng Fortuna. Tôi không biết nhiều về điều này, nhưng bạn có thể điều tra.

Tôi cũng nên đề cập rằng mặc dù rất nguy hiểm khi sử dụng SecureRandomthuật toán và / hoặc nguồn ngẫu nhiên được triển khai kém , bạn có thể cuộn Nhà cung cấp JCE của riêng mình với cách triển khai tùy chỉnh SecureRandomSpi. Bạn sẽ cần trải qua một quá trình với Sun để được nhà cung cấp của bạn ký hợp đồng, nhưng thực sự nó khá đơn giản; họ chỉ cần bạn fax cho họ một biểu mẫu cho biết bạn biết về các hạn chế xuất khẩu của Hoa Kỳ đối với các thư viện tiền điện tử.


Các nhà cung cấp JCE khác nhau đó chỉ được sử dụng nếu họ sử dụng một nguồn entropy khác, điều đó có nghĩa là họ phải sử dụng một phần cứng cụ thể, chẳng hạn như HSM. Mặt khác, chúng có khả năng gặp phải sự chậm lại, tùy thuộc vào mức độ entropy mà chúng trích xuất từ ​​hệ thống.
Maarten Bodewes

3

Sử dụng ngẫu nhiên an toàn làm nguồn khởi tạo cho thuật toán định kỳ; bạn có thể sử dụng một twister Mersenne cho công việc hàng loạt thay vì một trong UncommonMath, đã xuất hiện được một thời gian và được chứng minh tốt hơn so với prng khác

http://en.wikipedia.org/wiki/Mersenne_twister

Đảm bảo làm mới ngay bây giờ và sau đó là ngẫu nhiên an toàn được sử dụng để khởi tạo, ví dụ: bạn có thể có một ngẫu nhiên an toàn được tạo cho mỗi khách hàng, sử dụng một trình tạo ngẫu nhiên giả ngẫu nhiên mersenne cho mỗi khách hàng, đạt được mức độ ngẫu nhiên đủ cao


2
Câu trả lời này là sai: twers Mersenne không phải là trình tạo số ngẫu nhiên an toàn. Nó sẽ là một thuật toán tốt cho Random, nhưng không phải cho SecureRandom.
Maarten Bodewes

3

Theo tài liệu này , các thuật toán khác nhau được SecureRandom sử dụng theo thứ tự ưu tiên:

  • Trên hầu hết các hệ thống * NIX
    1. Bản địa
    2. SHA1PRNG
    3. Khóa bản địa
    4. NativePRNGNonBlocking
  • Trên các hệ thống Windows
    1. SHA1PRNG
    2. Windows-PRNG

Vì bạn đã hỏi về Linux, tôi bỏ qua việc triển khai Windows và cả SunPKCS11 chỉ thực sự có sẵn trên Solaris, trừ khi bạn tự cài đặt nó - và sau đó bạn sẽ không hỏi điều này.

Theo những tài liệu tương tự, những thuật toán này sử dụng là gì

SHA1PRNG
Việc gieo hạt ban đầu hiện được thực hiện thông qua sự kết hợp của các thuộc tính hệ thống và thiết bị thu thập entropy java.security.

NativePRNG
nextBytes() sử dụng /dev/urandom
generateSeed()sử dụng/dev/random

NativePRNGBlocking
nextBytes()generateSeed()sử dụng/dev/random

NativePRNGNonBlocking
nextBytes()generateSeed()sử dụng/dev/urandom

Điều đó có nghĩa là nếu bạn sử dụng SecureRandom random = new SecureRandom(), nó sẽ đi xuống danh sách đó cho đến khi nó tìm thấy một hoạt động, thường sẽ là NativePRNG. Và điều đó có nghĩa là nó tự tạo hạt giống từ /dev/random(hoặc sử dụng nó nếu bạn tạo rõ ràng một hạt giống), sau đó sử dụng /dev/urandomđể nhận các byte, ints, double, booleans, what-have-yous tiếp theo.

/dev/randomlà chặn (nó chặn cho đến khi nó có đủ entropy trong nhóm entropy), điều đó có thể cản trở hiệu suất.

Một giải pháp cho điều đó là sử dụng một cái gì đó như đã tạo ra đủ entropy, một giải pháp khác là sử dụng /dev/urandomthay thế. Mặc dù bạn có thể thiết lập điều đó cho toàn bộ jvm, một giải pháp tốt hơn là thực hiện nó cho trường hợp cụ thể này SecureRandombằng cách sử dụng SecureRandom random = SecureRandom.getInstance("NativePRNGNonBlocking"). Lưu ý rằng phương thức đó có thể ném NoSuchAlerskymException nếu NativePRNGNonBlocking, vì vậy hãy chuẩn bị để dự phòng về mặc định.

SecureRandom random;
try {
    random = SecureRandom.getInstance("NativePRNGNonBlocking");
} catch (NoSuchAlgorithmException nsae) {
    random = new SecureRandom();
}

Cũng lưu ý rằng trên các hệ thống * nix khác, /dev/urandomcó thể hoạt động khác đi .


/dev/urandomđủ ngẫu nhiên?

Sự khôn ngoan thông thường có nó là chỉ /dev/randomđủ ngẫu nhiên. Tuy nhiên, một số tiếng nói khác nhau. Trong "Cách đúng để sử dụng SecureRandom""Huyền thoại về / dev / urandom" , người ta cho rằng điều đó /dev/urandom/cũng tốt như vậy.

Người dùng trên ngăn xếp Bảo mật thông tin đồng ý với điều đó . Về cơ bản, nếu bạn phải hỏi, /dev/urandomtốt cho mục đích của bạn.


2

Tôi đã không tự mình chống lại vấn đề này, nhưng tôi đã tạo ra một chuỗi khi bắt đầu chương trình ngay lập tức cố gắng tạo ra một hạt giống, sau đó chết. Phương thức mà bạn gọi cho randoms sẽ tham gia vào luồng đó nếu nó còn sống nên cuộc gọi đầu tiên chỉ chặn nếu nó xảy ra rất sớm trong quá trình thực thi chương trình.


Đó là một hack khá cực đoan, nhưng nó có thể hoạt động; Người ta không nói rằng PRNG đã sử dụng có thể không sử dụng vật liệu hạt giống bổ sung mà vẫn có thể dẫn đến chặn. Sử dụng một số ngẫu nhiên khác nhau cung cấp hoặc sửa chữa entropy trong hệ thống nên được ưu tiên mạnh mẽ. Vì ít nhất nó có thể cung cấp một giải pháp tạm thời, tôi đã bỏ phiếu trả lời.
Maarten Bodewes

2

Kinh nghiệm của tôi chỉ là khởi tạo PRNG chậm chứ không phải tạo dữ liệu ngẫu nhiên sau đó. Hãy thử một chiến lược khởi tạo háo hức hơn. Vì chúng rất tốn kém để tạo ra, hãy coi nó như một đĩa đơn và sử dụng lại cùng một ví dụ. Nếu có quá nhiều tranh chấp luồng cho một thể hiện, gộp chúng hoặc biến chúng thành luồng cục bộ.

Đừng thỏa hiệp về việc tạo số ngẫu nhiên. Một điểm yếu ở đó làm tổn hại tất cả an ninh của bạn.

Tôi không thấy nhiều máy phát điện dựa trên nguyên tử phân rã COTS, nhưng có một số kế hoạch cho chúng, nếu bạn thực sự cần nhiều dữ liệu ngẫu nhiên. Một trang web luôn có những điều thú vị để xem, bao gồm HotBits, là Fourmilab của John Walker's.


1
Tôi đã luôn tự hỏi về điều này, vì các sản phẩm phân rã tau mãn tính gần như đạt được lý tưởng về một nguồn ngẫu nhiên, tôi không thể thoát khỏi mong muốn sử dụng nó thay vì các công cụ thuật toán. Vì mục đích của op, tôi đã quyết định từ lâu rằng một số thời gian trước là đặc hữu đối với tất cả các công cụ bảo mật. Nếu một người sẽ cần một bộ tạo ngẫu nhiên, có thể được gọi trong hàm tạo và chỉ cần nhớ xây dựng một cái khi tải trang, nó sẽ bị chôn vùi dưới sự hoán đổi avl và thậm chí là khó chọn như tôi không chú ý.
Nicholas Jordan

Chipset Intel 8xx (và có lẽ nhiều loại khác) có RNG phần cứng sử dụng nhiễu nhiệt, một hiệu ứng lượng tử thực sự khó lường. Mô-đun nền tảng đáng tin cậy cũng có thể chứa RNG phần cứng, nhưng thật không may, cái trong máy tính xách tay của tôi thì không.
erickson

Nó phụ thuộc vào RNG cụ thể nếu nó gieo hạt một lần hoặc nếu nó chín sau một thời gian. NIST chỉ định PRNG đã đổi mới, nhưng nhiều triển khai phần mềm thì không. Tái cấu trúc mã xung quanh một singleton là một ý tưởng khủng khiếp, đặc biệt là về các triển khai đa luồng; tốt hơn là khắc phục nguồn gốc của vấn đề: việc gieo hạt chậm do thiếu entropy. Nếu bạn sử dụng một singleton, hãy sử dụng nó để cung cấp hạt giống cho các triển khai SecureRandom khác hoàn toàn mang tính quyết định. Kiểu thiết kế này có lẽ đòi hỏi khá nhiều kiến ​​thức mặc dù.
Maarten Bodewes

@MaartenBodewes Đó là những điểm tốt. Nếu việc triển khai là một khối, chờ đợi entropy hệ thống, tôi nghĩ rằng coi nó như một đơn vị trong ứng dụng của bạn không phải là một ý tưởng khủng khiếp vì nguồn bên dưới thực sự là một đơn vị. Nhưng sử dụng một ví dụ đó để gieo hạt giống cho người khác là một gợi ý tốt, ngay cả khi phức tạp. Tôi không chắc chắn, nhưng tôi nghĩ rằng nhà cung cấp Mặt trời (và sau đó là Oracle) SecureRandomđã thay đổi một vài lần trong 10 năm qua trong việc thu thập entropy của nó.
erickson

Tôi rất chắc chắn rằng nó đã thay đổi khá nhiều lần, đến mức tôi sẽ không thử và đặt tất cả các thay đổi trong nhận xét này :). Ít có khả năng chậm SecureRandomvẫn là một vấn đề, nhưng entropy thấp trong một hệ thống sẽ luôn luôn là vấn đề. Sử dụng một singleton sẽ tạo ra mã được ghép mạnh mẽ, đó là một mẫu chống thiết kế. Do đó, nó nên được sử dụng hết sức cẩn thận; tốt nhất là bạn phải đảo ngược tất cả các tham chiếu trong mã nếu bạn sẽ khắc phục vấn đề.
Maarten Bodewes

2

Có vẻ như bạn nên rõ ràng hơn về các yêu cầu RNG của bạn. Yêu cầu RNG mật mã mạnh nhất (theo tôi hiểu) sẽ là ngay cả khi bạn biết thuật toán được sử dụng để tạo chúng và bạn biết tất cả các số ngẫu nhiên được tạo trước đó, bạn không thể nhận được bất kỳ thông tin hữu ích nào về bất kỳ số ngẫu nhiên nào được tạo trong tương lai, mà không tốn một lượng sức mạnh tính toán không thực tế.

Nếu bạn không cần sự đảm bảo đầy đủ về tính ngẫu nhiên này thì có thể có sự đánh đổi hiệu suất phù hợp. Tôi có xu hướng đồng ý với phản hồi của Dan Dyer về AESC gặpRNG từ Uncommons-Maths hoặc Fortuna (một trong những tác giả của nó là Bruce Schneier, một chuyên gia về mật mã học). Tôi chưa bao giờ sử dụng nhưng những ý tưởng có vẻ có uy tín từ cái nhìn đầu tiên.

Tôi nghĩ rằng nếu bạn có thể tạo một hạt ngẫu nhiên ban đầu theo định kỳ (ví dụ một lần mỗi ngày hoặc mỗi giờ hoặc bất cứ điều gì), bạn có thể sử dụng một mật mã luồng nhanh để tạo các số ngẫu nhiên từ các đoạn liên tiếp của luồng (nếu mật mã luồng sử dụng XOR thì chỉ cần truyền vào một luồng null hoặc lấy trực tiếp các bit XOR). ECRYPT của eStreamdự án có rất nhiều thông tin tốt bao gồm cả điểm chuẩn hiệu suất. Điều này sẽ không duy trì entropy giữa các điểm mà bạn bổ sung kịp thời, vì vậy nếu ai đó biết một trong các số ngẫu nhiên và thuật toán bạn đã sử dụng, về mặt kỹ thuật có thể, với rất nhiều sức mạnh tính toán, để phá vỡ mật mã luồng và đoán trạng thái bên trong của nó để có thể dự đoán các số ngẫu nhiên trong tương lai. Nhưng bạn phải quyết định liệu rủi ro đó và hậu quả của nó có đủ để biện minh cho chi phí duy trì entropy hay không.

Chỉnh sửa: đây là một số ghi chú khóa học mật mã trên RNG tôi tìm thấy trên mạng 'trông rất phù hợp với chủ đề này.


1
"Fortuna (một trong những tác giả của nó là Bruce Schneier, một chuyên gia về mật mã học)" - và người còn lại là Niels Ferguson, một chuyên gia về mật mã học :-)
Steve Jessop

2

Nếu phần cứng của bạn hỗ trợ, hãy thử sử dụng Java RdRand Utility mà tôi là tác giả.

Nó dựa trên RDRANDhướng dẫn của Intel và nhanh hơn khoảng 10 lần so với SecureRandomvà không có vấn đề về băng thông để thực hiện khối lượng lớn.


Lưu ý rằng việc triển khai này chỉ hoạt động trên các CPU cung cấp hướng dẫn (nghĩa là khi rdrandcờ bộ xử lý được đặt). Bạn cần phải khởi tạo nó một cách rõ ràng thông qua hàm RdRandRandom()tạo; không có cụ thể Providerđã được thực hiện.


3
Bạn có thể muốn đọc people.umass.edu/gbecker/BeckerChes13.pdf và chắc chắn không bao giờ chỉ sử dụng dữ liệu Intel RDRAND. Luôn trộn nó với một số dữ liệu không thể đoán trước khác, chẳng hạn như đầu ra của mật mã luồng aRC4 (được tạo từ / dev / urandom và với một vài KiB đầu ra bị loại bỏ vì sai lệch đã biết).
mirabilos

1 mirabilos. Tôi nghĩ RDRANDlà một nguồn tốt, nhưng nó không đáng tin cậy một chút. Nó chắc chắn cần phải là một đầu vào của nhiều người vào một nhà sưu tập (không xúc phạm đến David Johnston).
jww

Tôi đã bỏ phiếu, sửa liên kết và cung cấp một số thông tin cơ bản. Nếu bạn không đồng ý, vui lòng quay lại chỉnh sửa.
Maarten Bodewes

1

Một cái gì đó khác để xem xét là thuộc tính securandom.source trong tệp lib / security / java.security

Có thể có một lợi ích hiệu suất khi sử dụng / dev / urandom thay vì / dev / ngẫu nhiên. Hãy nhớ rằng nếu chất lượng của các số ngẫu nhiên là quan trọng, đừng tạo ra sự thỏa hiệp làm mất an ninh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.