Tùy chọn java.security.egd dùng để làm gì?


22

Trong một dự án tôi đang làm việc, ứng dụng được khởi chạy bằng lệnh tương tự như sau:

java -Djava.security.egd=file:/dev/urandom -jar app.jar

Tôi chưa bao giờ thấy java.security.egdtùy chọn này trước đây. Tìm kiếm một chút, nó dường như được sử dụng để định cấu hình tạo số ngẫu nhiên trong một ứng dụng Java.

Đúng không? Khi nào được cho là sẽ được áp dụng?

Câu trả lời:


29

Các ứng dụng Java có thể và nên sử dụng lớp java.security.SecureRandom để tạo ra các giá trị ngẫu nhiên mạnh về mặt mật mã bằng cách sử dụng trình tạo số giả ngẫu nhiên mã hóa mạnh ( CSPRNG ). Việc triển khai JDK tiêu chuẩn của lớp java.util.Random không được coi là mạnh về mặt mật mã.

Các hệ điều hành giống như Unix có /dev/random, một tệp đặc biệt phục vụ các số ngẫu nhiên giả truy cập vào tiếng ồn môi trường được thu thập từ trình điều khiển thiết bị và các nguồn khác. Tuy nhiên, nó chặn nếu có ít entropy có sẵn hơn yêu cầu ; /dev/urandomthường không bao giờ chặn, ngay cả khi hạt giống trình tạo số giả ngẫu nhiên không được khởi tạo hoàn toàn với entropy kể từ khi khởi động. Vẫn còn một tệp đặc biệt thứ 3, /dev/arandomchặn sau khi khởi động cho đến khi hạt giống được khởi tạo an toàn với đủ entropy, và sau đó không bao giờ chặn nữa.

Theo mặc định, JVM khởi tạo lớp SecureRandom bằng cách sử dụng /dev/random, do đó mã Java của bạn có thể chặn bất ngờ . Tùy chọn -Djava.security.egd=file:/dev/./urandomtrong lời gọi dòng lệnh được sử dụng để bắt đầu quá trình Java báo cho JVM sử dụng /dev/urandomthay thế.

Phần bổ sung /./dường như làm cho JVM sử dụng thuật toán SHA1PRNG sử dụng SHA-1 làm nền tảng của PRNG (Pseudo Random Number Generator). Nó mạnh hơn thuật toán NativePRNG được sử dụng khi /dev/urandomđược chỉ định.

Cuối cùng, có một huyền thoại /dev/urandomlà một trình tạo số ngẫu nhiên giả, PRNG, trong khi đó /dev/randomlà một trình tạo số ngẫu nhiên đúng . Điều này chỉ đơn giản là không đúng sự thật, cả hai /dev/random/dev/urandomđược cung cấp bởi cùng một CSPRNG (trình tạo số giả ngẫu nhiên bảo mật bằng mật mã). Chỉ hành vi khi nhóm tương ứng của họ hết entropy, theo một số ước tính, khác nhau: /dev/randomkhối, trong khi /dev/urandomkhông.

Thế còn entropy sắp hết? Nó không thành vấn đề.

Nó chỉ ra rằng, việc tìm kiếm ngẫu nhiên là một yêu cầu cơ bản cho rất nhiều khối xây dựng mật mã của chúng tôi. Và nếu bạn lấy đầu ra của hàm băm mật mã, nó phải không thể phân biệt được với một chuỗi ngẫu nhiên để mật mã sẽ chấp nhận nó. Đó là lý do của việc sử dụng thuật toán SHA1PRNG, vì nó sử dụng hàm băm và bộ đếm, cùng với một hạt giống.

Khi nào được cho là sẽ được áp dụng?

Luôn luôn, tôi muốn nói.

Nguồn:
https://gist.github.com/aussc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom


EDIT 04/2020:

Một nhận xét đề cập đến một sự thay đổi về hành vi của lớp SecureRandom trong Java 8.

SHA1PRNG và NativePRNG đã được sửa để tôn trọng đúng các thuộc tính nguồn gốc của SecureRandom trong tệp java.security. (Cách giải quyết tối nghĩa bằng cách sử dụng tệp: /// dev / urandom và tệp: / dev /./ urandom không còn cần thiết.)

Điều này đã được chỉ ra bởi các thử nghiệm được tham chiếu trên phần Nguồn ở trên. Phần bổ sung /./được yêu cầu để thay đổi thuật toán được SecureRanom sử dụng trong Java 8 từ NativePRNG sang SHA1PRNG.

Tuy nhiên, tôi có một số tin tức mà tôi muốn chia sẻ. Theo JEP-273 , kể từ Java 9, lớp SecureRandom thực hiện ba cơ chế Trình tạo bit ngẫu nhiên xác định (DRBG) được mô tả trong NIST 800-90Ar1 . Các cơ chế này thực hiện các thuật toán hiện đại mạnh như SHA-512 và AES-256.

JDK có hai loại triển khai SecureRandom :

  • Một là phụ thuộc vào nền tảng và dựa trên các cuộc gọi gốc hoặc thiết bị HĐH như đọc /dev/{u}randomtrên Unix hoặc sử dụng CryptoAPI trên Windows. Các bản phát hành mới nhất của Linux và Windows đã hỗ trợ DRBG, nhưng các bản phát hành cũ hơn và các hệ thống nhúng có thể không .
  • Loại khác là một triển khai Java thuần túy sử dụng triển khai RNG dựa trên SHA1 cũ hơn, không mạnh bằng các thuật toán được sử dụng bởi các cơ chế DRBG được phê duyệt.

Trong khi đó , Hướng dẫn dành cho nhà phát triển bảo mật Java 13 vẫn đọc

Trên Linux và macOS, nếu thiết bị thu thập entropy trong java.security được đặt thành file:/dev/urandomhoặc file:/dev/random, thì NativePRNG được ưu tiên hơn SHA1PRNG. Mặt khác, SHA1PRNG được ưu tiên.

Để làm rõ cách các cơ chế DRBG mới chơi cùng với các PRNG trước đó, tôi chạy một số thử nghiệm trên macOS (Darwin) với AdoptOpenJDK (bản dựng 13.0.2 + 8). Đây là kết quả:

tệp: / dev / ngẫu nhiên
Thứ tự ưu tiên cho nhà cung cấp:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

tệp: / dev / urandom
Thứ tự ưu tiên cho nhà cung cấp:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

tệp: / dev /./ urandom
Thứ tự ưu tiên cho nhà cung cấp:

SecureRandom.DRBG
SecureRandom.SHA1PRNG
SecureRandom.NativePRNG

Phần kết luận:

Tôi khuyên bạn nên sử dụng -Djava.security.egd=file:/dev/./urandomđể đảm bảo tận dụng triển khai SecureRandom mạnh nhất có sẵn bất kể nền tảng được sử dụng trong khi tránh việc mã bị chặn bất ngờ.


1
Kể từ Java 8, "cách giải quyết tối nghĩa" của phần bổ sung ./ trong tên tệp không còn cần thiết nữa, vì vậy bạn chỉ cần sử dụng "/ dev / urandom", xem: docs.oracle.com/javase/8/docs / kỹ thuật / hướng dẫn / bảo mật / đào
Kamal

Cảm ơn bạn đã cập nhật câu trả lời (đặc biệt về các thay đổi trong Java 9 và 13). Theo hiểu biết của tôi, kể từ khi Java 8 đặt "thiết bị thu thập entropy" thành / dev / urandom hoặc /dev/./urandom sẽ mang lại kết quả chính xác như nhau, nếu không thì việc khắc phục sẽ không có ý nghĩa. Từ góc độ hệ điều hành, những điểm đó đến cùng một tệp giống nhau, do đó không ảnh hưởng đến Java (nó đã được sửa trước đó, nhưng đó là một lỗi, không phải là một tính năng dự định). Do đó, tuyên bố của bạn "Thêm /./ là bắt buộc để ảnh hưởng đến lựa chọn PRNG." không còn đúng nữa, kể từ Java 8.
Kamal

Cảm ơn @Kamal cho ý kiến ​​của bạn. Cụm từ trước đây của tôi "lựa chọn PRNG" không đủ rõ ràng. Tôi đã đọc lại nó để làm rõ Tôi đang nói về thuật toán được sử dụng: NativePRNG hoặc SHA1PRNG. Việc sử dụng các /dev/urandomlựa chọn NativePRNG được cung cấp /dev/urandomtrong khi /dev/./urandomchọn SHA1PRNG (cũng được cung cấp bởi /dev/urandom) khi sử dụng Java 8. Từ Java 9 trở đi, DRBG được ưu tiên khi /dev/./urandomnguồn được chỉ định.
dbaltor

1

Điều này không còn cần thiết nếu bạn đang sử dụng JDK 8 trở lên

Vấn đề đã được Java khắc phục và đây là một số liên kết

Đề cương

SHA1PRNG và NativePRNG đã được sửa để tôn trọng đúng các thuộc tính nguồn gốc của SecureRandom trong tệp java.security. (Cách giải quyết tối nghĩa bằng cách sử dụng tệp: /// dev / urandom và tệp: / dev /./ urandom không còn cần thiết.)

Để biết thêm thông tin (tìm kiếm ngẫu nhiên trong trang):

https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html

https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html


Tôi không tin điều này là chính xác. Đối với nền: tersesystems.com/blog/2015/12/17/ Nhật Bản Các bản sửa lỗi trong Java 8 chỉ nói rằng bây giờ chúng tôn trọng các thuộc tính nguồn gốc của SecureRandom trong tệp java.security. Nhưng theo mặc định, nó vẫn chứa: seckerandom.source = file: / dev / ngẫu nhiên "cách giải quyết tối nghĩa" đề cập đến ./ trong tên tệp, cũng được đề cập bởi câu trả lời được chấp nhận (và được bình chọn nhiều nhất) ở đây.
Kamal

"Cách giải quyết tối nghĩa" chỉ được yêu cầu trong các trường hợp cụ thể, xem: bug.java.com/bugdatabase/view_orms.do?orms_id=6202721
Kamal

@Kamal Các liên kết bạn đã đăng đề cập đến Java 6 trở về trước,
Venu Madhav

Đó chính xác là vấn đề, nó đã được sửa trong Java 8. Theo báo cáo lỗi, "cách giải quyết tối nghĩa" (thêm phần bổ sung ./ trong tên tệp) là bắt buộc sau Java 1.4.2 và lên đến 6. Tôi giả sử trong Java 7 cũng vậy, nếu không, nó sẽ không được đề cập như đã sửa trong Java 8. Mặc dù vậy, vẫn cần cài đặt / dev / urandom thay vì / dev / ngẫu nhiên, nếu bạn muốn sử dụng thiết bị không chặn.
Kamal

0

Điều này có liên quan đến sự khác biệt của linux /dev/randomvà trình /dev/urandomtạo số ngẫu nhiên.

Lấy từ liên kết này

Java Bug 6202721 nói rằng java.security.SecureRandom sử dụng / dev / ngẫu nhiên thay vì / dev / urandom ngay cả khi / dev / urandom được chỉ định vì tại thời điểm đó (khoảng năm 2004) / dev / urandom không hoạt động đúng. Lỗi chưa bao giờ được đảo ngược khi / dev / urandom hoạt động khá tốt. Do đó, bạn phải giả mạo nó bằng cách che khuất cài đặt bằng cách sử dụng /dev/./urandom để buộc sử dụng SHA1PRNG thay vì / dev / ngẫu nhiên.

Để trả lời câu hỏi của bạn

Khi nào được cho là sẽ được áp dụng?

Dựa trên liên kết trên, đó là một cái gì đó duy nhất cho các phiên bản Java 5 và sau đó xuất phát từ các vấn đề với / dev / urandom trên các hệ thống Linux vào năm 2004.


Có lẽ có một lỗi đánh máy trong bài viết đó, vì Java Bug 6202721 thực sự nói rằng "Đây là vấn đề nếu / dev / urandom được chọn vì / dev / ngẫu nhiên không hoạt động đúng.". Do đó, kết luận của bạn "xuất phát từ các vấn đề với / dev / urandom" là không chính xác. Xem câu trả lời được chấp nhận để được giải thích về việc chọn / dev / urandom thay vì mặc định (/ dev / ngẫu nhiên). Đó là một ý tưởng tốt trong hầu hết các trường hợp.
Kamal
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.