Chủ đề SecureRandom có ​​an toàn không?


103

SecureRandomchủ đề an toàn không? Tức là, sau khi khởi tạo nó, có thể dựa vào việc truy cập vào số ngẫu nhiên tiếp theo để an toàn cho luồng không? Việc kiểm tra mã nguồn dường như cho thấy điều đó, và báo cáo lỗi này dường như chỉ ra rằng việc thiếu tài liệu làm an toàn luồng là một vấn đề javadoc. Có ai xác nhận rằng nó trong thực tế là chủ đề an toàn?

Câu trả lời:


108

Vâng, đúng vậy. Nó mở rộng Random, luôn có triển khai an toàn luồng trên thực tế , và từ Java 7, đảm bảo rõ ràng an toàn luồng.

Nếu nhiều luồng đang sử dụng một luồng duy nhất SecureRandom, có thể có sự tranh cãi làm ảnh hưởng đến hiệu suất. Mặt khác, việc khởi tạo một SecureRandomthể hiện có thể tương đối chậm. Việc chia sẻ RNG toàn cầu là tốt nhất hay tạo một RNG mới cho mỗi luồng sẽ tùy thuộc vào ứng dụng của bạn. Các ThreadLocalRandomlớp có thể được sử dụng như một mô hình để cung cấp một giải pháp mà hỗ trợ SecureRandom.


3
Cảm ơn các cập nhật. Thật kỳ lạ, lỗi được đánh dấu là đã đóng là "sẽ không sửa". Nhưng họ đã sửa nó bằng cách nào. Ồ, tôi không ghen tị với họ về kích thước cơ sở dữ liệu lỗi của họ.
Yishai

4
khởi tạo một SecureRandomthể không chỉ là chậm, nhưng có khả năng có thể treo vì thiếu entropy
Walter Tross

8
Xin lưu ý rằng ThreadLocalRandom rất dễ bị bẻ khóa, vì vậy nếu bạn định giới thiệu giá trị đã tạo ra cho thế giới, hãy sử dụng SecureRandom thay vì jazzy.id.au/default/2010/09/20/…
walv

2
Tôi sẽ đi ra ngoài ở đây và nói rằng câu trả lời này là không chính xác. Hợp đồng cho Ngẫu nhiên, đảm bảo an toàn luồng, không ràng buộc đối với các lớp con. Chắc chắn tất cả các thuộc tính khác của Random được ghi lại không ràng buộc trên các lớp con, vì vậy tôi không hiểu tại sao nên giả định an toàn luồng.
Tổng thống James K. Polk

2
@JamesKPolk Việc không bảo toàn thuộc tính của supertype sẽ vi phạm nguyên tắc thay thế.
erickson

11

Việc triển khai hiện tại SecureRandomlà an toàn theo luồng, đặc biệt là hai phương pháp đột biến nextBytes(bytes[])setSeed(byte[])được đồng bộ hóa.

Chà, theo như tôi có thể nói, tất cả các phương thức đột biến cuối cùng đều được định tuyến thông qua hai phương thức đó và SecureRandomghi đè một vài phương thức Randomđể đảm bảo điều đó. Phương pháp này hoạt động nhưng có thể bị hỏng nếu việc triển khai bị thay đổi trong tương lai.

Giải pháp tốt nhất là đồng bộ hóa thủ công trên SecureRandomphiên bản đầu tiên. Điều này có nghĩa là mỗi ngăn xếp cuộc gọi sẽ thu được hai khóa trên cùng một đối tượng, nhưng điều đó thường rất rẻ trên các JVM hiện đại. Có nghĩa là, không có nhiều tác hại trong việc đồng bộ hóa rõ ràng bản thân. Ví dụ:

    SecureRandom rnd = ...;

    byte[] b = new byte[NRANDOM_BYTES];
    synchronized (rnd) {
        rnd.nextBytes(b);
    }

3
Ít nhất trong JDK 10, SecureRandom dựa trên một nhà cung cấp và kiểm tra xem nhà cung cấp có an toàn chuỗi hay không, chỉ đồng bộ hóa nếu không, trong nextBytes.
nafg

java.security.SecureRandom#nextBytestrong Java 8 không được đồng bộ hóa. Bạn có thể vui lòng chỉ định phiên bản Java nào mà bạn tìm thấy đã được đồng bộ hóa #nextByteskhông ?.
Jaime Hablutzel
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.