เธรด SecureRandom ปลอดภัยหรือไม่


103

คือSecureRandomความปลอดภัยด้าย? นั่นคือหลังจากกำหนดค่าเริ่มต้นแล้วจะสามารถเข้าถึงหมายเลขสุ่มถัดไปได้เพื่อให้เธรดปลอดภัยหรือไม่? การตรวจสอบซอร์สโค้ดดูเหมือนจะแสดงให้เห็นว่าเป็นเช่นนั้นและดูเหมือนว่ารายงานข้อบกพร่องนี้จะบ่งชี้ว่าไม่มีเอกสารประกอบเนื่องจากเธรดปลอดภัยเป็นปัญหาของ javadoc มีใครยืนยันว่าปลอดภัยจริง?

คำตอบ:


108

ใช่แล้ว. มันขยายออกไปRandomซึ่งมีการใช้งานเธรดที่ปลอดภัยโดยพฤตินัยเสมอและจากJava 7 รับประกันความปลอดภัยของเธรดอย่างชัดเจน

หากหลายเธรดกำลังใช้เธรดเดียวSecureRandomอาจมีความขัดแย้งที่ส่งผลต่อประสิทธิภาพ ในทางกลับกันการเริ่มต้นSecureRandomอินสแตนซ์อาจค่อนข้างช้า ไม่ว่าจะเป็นการดีที่สุดในการแบ่งปัน RNG ทั่วโลกหรือสร้างใหม่สำหรับแต่ละเธรดจะขึ้นอยู่กับแอปพลิเคชันของคุณ ระดับสามารถนำมาใช้เป็นรูปแบบการให้บริการโซลูชั่นที่สนับสนุนThreadLocalRandomSecureRandom


3
ขอบคุณสำหรับการอัพเดท. ผิดปกติข้อบกพร่องถูกทำเครื่องหมายว่า "จะไม่แก้ไข" แต่พวกเขาก็แก้ไขมันอยู่ดี โอ้ฉันไม่อิจฉาพวกเขาขนาดฐานข้อมูลบั๊ก
Yishai

4
การเริ่มต้นSecureRandomไม่เพียง แต่จะช้าเท่านั้น แต่ยังสามารถหยุดทำงานได้เนื่องจากเอนโทรปีที่หายไป
Walter Tross

8
โปรดทราบว่า ThreadLocalRandom นั้นแตกง่ายมากดังนั้นหากคุณวางแผนที่จะเปิดเผยมูลค่าที่สร้างขึ้นไปทั่วโลกให้ใช้ SecureRandom แทนjazzy.id.au/default/2010/09/20/…
walv

2
ฉันจะออกไปข้างนอกที่นี่และบอกว่าคำตอบนี้ไม่ถูกต้อง สัญญาสำหรับ Random ซึ่งรับประกันความปลอดภัยของเธรดไม่มีผลผูกพันกับคลาสย่อย แน่นอนว่าคุณสมบัติอื่น ๆ ทั้งหมดของ Random ที่บันทึกไว้ไม่ได้ผูกมัดกับคลาสย่อยดังนั้นฉันจึงไม่เห็นว่าเหตุใดจึงควรถือว่าความปลอดภัยของเธรด
ประธาน James K. Polk

2
@JamesKPolk ความล้มเหลวในการรักษาคุณสมบัติของ supertype จะละเมิดหลักการทดแทน
erickson

11

การใช้งานปัจจุบันของSecureRandomเธรดปลอดภัยโดยเฉพาะสองวิธีการกลายพันธุ์nextBytes(bytes[])และsetSeed(byte[])มีการซิงโครไนซ์

เท่าที่ฉันสามารถบอกได้ในที่สุดวิธีการกลายพันธุ์ทั้งหมดจะถูกกำหนดเส้นทางผ่านสองวิธีนี้และSecureRandomแทนที่วิธีการบางอย่างRandomเพื่อให้แน่ใจว่า ซึ่งใช้งานได้ แต่อาจเปราะบางหากมีการเปลี่ยนแปลงการนำไปใช้ในอนาคต

ทางออกที่ดีที่สุดคือการซิงโครไนSecureRandomซ์อินสแตนซ์ด้วยตนเองก่อน ซึ่งหมายความว่าสแต็กการโทรแต่ละชุดจะได้รับการล็อกสองรายการในวัตถุเดียวกัน แต่โดยปกติจะมีราคาถูกมากสำหรับ JVM สมัยใหม่ นั่นคือไม่มีอันตรายมากนักในการซิงโครไนซ์ตัวเองอย่างชัดเจน ตัวอย่างเช่น:

    SecureRandom rnd = ...;

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

3
อย่างน้อยที่สุดใน JDK 10 SecureRandom จะขึ้นอยู่กับผู้ให้บริการและตรวจสอบว่าผู้ให้บริการนั้นปลอดภัยหรือไม่โดยจะซิงโครไนซ์หากไม่ใช่ใน nextBytes
nafg

java.security.SecureRandom#nextBytesใน Java 8 ไม่ซิงโครไนซ์ คุณช่วยระบุเวอร์ชัน Java ที่คุณพบว่ามีการซิงโครไนซ์#nextBytesหรือไม่
Jaime Hablutzel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.