วิธีจัดการกับตัวสร้าง SecureRandom ที่ช้าจะทำอย่างไร


165

ถ้าคุณต้องการตัวเลขที่แข็งแกร่งใน Java SecureRandomคุณใช้ น่าเสียดายที่SecureRandomอาจช้ามาก ถ้ามันใช้/dev/randomบน Linux มันสามารถบล็อกรอเอนโทรปีเพียงพอที่จะสร้างขึ้น คุณจะหลีกเลี่ยงบทลงโทษการแสดงได้อย่างไร?

มีใครใช้Uncommon Mathsเป็นวิธีการแก้ปัญหานี้หรือไม่?

ใครช่วยยืนยันว่าปัญหาประสิทธิภาพนี้ได้รับการแก้ไขใน JDK 6 หรือไม่


ดูเหมือนว่าสิ่งนี้เกี่ยวข้องกับความช้าของSecureRandom.generateSeed () มีข้อบกพร่องที่ถูกปฏิเสธอธิบายถึงความช้าและวิธีแก้ปัญหา: JDK-6521844: SecureRandom แฮงค์บนระบบ Linux
AlikElzin-kilaka

ตรวจสอบ / dev / urandom (ไม่ใช่ / dev / random) .. พิจารณาเพียงแค่รับเมล็ดกำเนิดตัวเลขสุ่มจาก urandom หากมีปัญหาการปิดกั้น
jcalfee314

Windows เกี่ยวข้องกับ: stackoverflow.com/questions/49322948/…
patrikbeno

คำตอบ:


80

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

ถ้าคุณต้องการ PRNG ให้ทำสิ่งนี้:

SecureRandom.getInstance("SHA1PRNG");

สิ่งที่ได้รับการสนับสนุนสตริงขึ้นอยู่กับSecureRandomผู้ให้บริการ SPI แต่คุณสามารถระบุพวกเขาโดยใช้และSecurity.getProviders()Provider.getService()

ซุนชอบ SHA1PRNG ดังนั้นจึงมีวางจำหน่ายอย่างแพร่หลาย มันไม่เร็วโดยเฉพาะอย่างยิ่งเมื่อ PRNGs ไป แต่ PRNGs จะเป็นเพียงตัวเลขที่คดเคี้ยวไม่ใช่การปิดกั้นการวัดเอนโทรปีทางกายภาพ

ยกเว้นว่าถ้าคุณไม่ได้โทรหาsetSeed()ก่อนที่จะได้รับข้อมูลแล้วจะ PRNG เมล็ดพันธุ์ตัวเองเมื่อครั้งแรกที่คุณโทรหาหรือnext() nextBytes()มันมักจะทำสิ่งนี้โดยใช้ข้อมูลสุ่มจริงจำนวนเล็กน้อยจากระบบ การโทรนี้อาจบล็อก แต่จะทำให้แหล่งที่มาของตัวเลขสุ่มมีความปลอดภัยมากกว่าตัวแปร "แฮชเวลาปัจจุบันพร้อมกับ PID เพิ่ม 27 และหวังว่าจะดีที่สุด" หากทุกอย่างที่คุณต้องการคือตัวเลขสุ่มสำหรับเกมหรือหากคุณต้องการให้สตรีมสามารถทำซ้ำได้ในอนาคตโดยใช้เมล็ดพันธุ์เดียวกันเพื่อการทดสอบเมล็ดพันธุ์ที่ไม่ปลอดภัยยังคงมีประโยชน์


คณิตศาสตร์ที่ผิดปกติจะดาวน์โหลดข้อมูลจากอินเทอร์เน็ตเพื่อทำการเพาะเท่านั้น แต่จะไม่ส่งคืนข้อมูลแบบสุ่มเมื่อสร้างตัวเลขสุ่ม
Dan Dyer

เช่นเดียวกันกับ SecureRandom - / dev / urandom เป็นเพียงสำหรับการเพาะ
AviD

อ๋อ เมื่อผู้ถามตอบว่า "ถ้าคุณต้องการหมายเลขสุ่มที่คุณใช้ SecureRandom - อาจช้า" ฉันคิดว่าบางทีเขาใช้ getSeed สำหรับทุกสิ่งและดูดพลังเอนโทรปีของเขา การแก้ไขไม่ได้ที่จะได้รับ JDK 6 ก็ใช้งาน SecureRandom วิธีที่มันตั้งใจ ;-)
สตีฟเจสซอพ

@Dan Dyer - ฉันได้แก้ไขความคิดเห็นของฉันเกี่ยวกับ Uncommon Maths แล้ว ฉันลองดูที่หน้าของคุณดังนั้นฉันรู้ว่าโดย "ตัวเลขสุ่ม" ฉันหมายถึง "สำหรับเมล็ดของมัน" แทนที่จะเป็น "เพื่อกลับไปที่ผู้ใช้" แต่คุณพูดถูกที่ไม่ใช่สิ่งที่ฉันพูด ...
Steve Jessop

"มันใช้ได้อย่างกว้างขวาง" มันไม่ได้รวมอยู่ในJDK ทุกรุ่นใช่หรือไม่ มันอยู่ในรายชื่อชื่อมาตรฐานความปลอดภัยของจาวา ... ( docs.oracle.com/javase/8/docs/technotes/guides/security/… )
Sean Reilly

176

คุณควรเลือก Linux / dev / urandom ที่เร็วขึ้น แต่มีความปลอดภัยน้อยโดยใช้:

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

อย่างไรก็ตามสิ่งนี้ใช้ไม่ได้กับ Java 5 และใหม่กว่า ( Java Bug 6202721 ) วิธีแก้ไขที่แนะนำคือการใช้:

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

(บันทึกเพิ่มเติม/./)


24
โปรดทราบว่ารายงาน Java Bug ระบุว่า "ไม่ใช่ข้อบกพร่อง" ในคำอื่น ๆ แม้ว่าค่าเริ่มต้นคือ/dev/urandomSun ถือเป็นสายเวทและใช้/dev/randomต่อไปดังนั้นคุณต้องปลอมมันออกมา เมื่อใดที่file:URL ไม่ใช่file:URL เมื่อใดก็ตามที่ Sun ตัดสินใจว่าไม่ใช่ :-(
Jim Garrison

6
หลังจากใช้เวลาสักครู่ในการตรวจสอบเรื่องนี้ดูเหมือนว่าการตั้งค่าปกติแม้จะfile:/dev/urandomอยู่ใน-Djava.security.egdหรือในsecurerandom.sourceไฟล์ java.security /dev/random/ก็ยังคงอ่านทุกครั้งSecureRandom.getSeed()(หรือsetSeed()เรียกว่า) การแก้ปัญหาด้วยfile:/dev/./urandomผลลัพธ์ไม่ได้อ่าน/dev/randomทั้งหมด (ยืนยันด้วย strace)
ด้าน b

7
/dev/urandomไม่ปลอดภัยน้อยกว่า/dev/randomเมื่อใช้งานกับ CSPRNG ที่ทันสมัย: en.wikipedia.org/wiki//dev/random#FreeBSD
lapo

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

1
อันไหนที่ถูก ? -Djava.security.egd = ไฟล์: / dev /./ urandom หรือไฟล์: /// dev / urandom @mattb
Aarish Ramesh

35

บน Linux การใช้งานเริ่มต้นสำหรับSecureRandomคือNativePRNG(ซอร์สโค้ดที่นี่ ) ซึ่งมีแนวโน้มที่จะช้ามาก บน Windows ค่าดีฟอลต์คือSHA1PRNGซึ่งคนอื่น ๆ ชี้ให้เห็นว่าคุณสามารถใช้บน Linux ได้หากคุณระบุไว้อย่างชัดเจน

NativePRNGแตกต่างจากAESCounterRNGSHA1PRNGและ Uncommons Maths ' ที่ได้รับเอนโทรปีอย่างต่อเนื่องจากระบบปฏิบัติการ (โดยการอ่านจาก) PRNG อื่นไม่ได้รับเอนโทรปีใด ๆ เพิ่มเติมหลังจากการเพาะ/dev/urandom

AESCounterRNG เป็นเรื่องเกี่ยวกับ 10x เร็วกว่าSHA1PRNGซึ่ง IIRC NativePRNGเป็นตัวที่สองหรือสามครั้งเร็วกว่า

หากคุณต้องการ PRNG ที่เร็วกว่าที่ได้รับเอนโทรปีหลังจากการเริ่มต้นให้ดูว่าคุณสามารถค้นหาการนำ Java ไปใช้ของFortunaได้หรือไม่ PRNG หลักของการใช้งาน Fortuna นั้นเหมือนกันกับที่ใช้โดย AESCounterRNG แต่ยังมีระบบที่ซับซ้อนของการรวมทรัพยากรเอนโทรปีและการกลับมาทำงานอัตโนมัติ


ลิงค์นี้ใช้งานไม่ได้ uncommons-maths.dev.java.net/nonav/api/org/uncommons/maths/... มีที่ไหนฉันเห็นนี่ไหม
UVM

@Unni เพิ่งอัปเดตลิงก์ โปรดทราบว่าประสิทธิภาพการเรียกร้องที่ฉันทำในคำตอบนี้อาจไม่ถูกต้องอีกต่อไป ฉันคิดว่าสิ่งต่าง ๆ อาจดีขึ้นใน Java เวอร์ชันล่าสุดและอาจมีความแตกต่างในประสิทธิภาพระหว่างแพลตฟอร์ม (เช่น Windows กับ Liux)
Dan Dyer

ฉันเพิ่งใช้ตัวอย่างหนึ่งของ SecureRandom ด้วย MessageDigest และทำ hexencoded มันการดำเนินการทั้งหมดใน Windows 7 PC ของฉันใช้เวลา 33 มิลลิวินาทีมันเป็นปัญหาฉันใช้ SHA1PRNG.SecureRandom prng = SecureRandom.getInstance ("SHA1PRN"); String randomNum = new Integer (prng.nextInt ()) .toString (); MessageDigest sha = MessageDigest.getInstance ("SHA-1"); result = sha.digest (randomNum.getBytes ()); str = hexEncode (ผลลัพธ์);
UVM

24

Linux distros ส่วนใหญ่ (ส่วนใหญ่ใช้ Debian) จะกำหนดค่า OpenJDK เพื่อใช้/dev/randomสำหรับเอนโทรปี

/dev/random คือโดยคำจำกัดความช้า (และยังสามารถบล็อก)

จากที่นี่คุณมีสองตัวเลือกในการยกเลิกการปิดกั้น:

  1. ปรับปรุงเอนโทรปีหรือ
  2. ลดความต้องการแบบแผน

ตัวเลือก 1 ปรับปรุงเอนโทรปี

หากต้องการเอนโทรปีมากขึ้นให้/dev/randomลองทำแฮงก์ภูตมันเป็นดีมอนที่รวบรวม HAVEGE เอนโทรปีอย่างต่อเนื่องและทำงานในสภาพแวดล้อมเสมือนจริงเพราะมันไม่จำเป็นต้องใช้ฮาร์ดแวร์พิเศษใด ๆ มีเพียงซีพียูและนาฬิกาเท่านั้น

บน Ubuntu / Debian:

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

บน RHEL / CentOS:

yum install haveged
systemctl enable haveged
systemctl start haveged

ตัวเลือก 2 ลดความต้องการแบบแผน

หากด้วยเหตุผลบางอย่างการแก้ปัญหาข้างต้นไม่ได้ช่วยหรือคุณไม่สนใจการสุ่มที่แข็งแกร่งของการเข้ารหัสคุณสามารถเปลี่ยนไปใช้ /dev/urandomใช้งานแทนซึ่งรับประกันได้ว่าจะไม่บล็อก

หากต้องการทำร่วมกันแก้ไขไฟล์jre/lib/security/java.securityในการติดตั้ง Java เริ่มต้นของคุณที่จะใช้/dev/urandom(เนื่องจากข้อผิดพลาดอื่นจะต้องมีการระบุเป็น/dev/./urandom )

แบบนี้:

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

จากนั้นคุณไม่จำเป็นต้องระบุในบรรทัดคำสั่ง


หมายเหตุ: หากคุณทำการเข้ารหัสคุณต้องมีเอนโทรปีที่ดี ตรงประเด็น - ปัญหา PRNG ของ Androidลดความปลอดภัยของกระเป๋าเงิน Bitcoin


โหวตคำตอบของคุณ แต่ " /dev/randomโดยคำจำกัดความช้า (และสามารถบล็อกได้)" ผิด มันขึ้นอยู่กับการกำหนดค่าระบบทั้งหมด เครื่องจักรใหม่กว่านี้อาจจะมีเช่น RNG รวดเร็วใน CPU ที่อาจจะนำมาใช้และเครื่อง BSD โดยทั่วไปมีการดำเนินการเหมือนกันสำหรับและ/dev/random /devl/urandomถึงกระนั้นคุณก็ไม่ควรเชื่อมั่นใน /dev/randomความรวดเร็ว บน VM คุณอาจต้องการติดตั้งชุดเครื่องมือไคลเอนต์บนไคลเอนต์ VM เพื่อให้สามารถใช้ RNG ของโฮสต์ระบบปฏิบัติการ
Maarten Bodewes

17

ฉันมีปัญหาคล้ายกันกับการโทรเพื่อSecureRandomบล็อกประมาณ 25 วินาทีต่อครั้งบนเซิร์ฟเวอร์ Debian ที่ไม่มีหัว ฉันติดตั้งhavegedดีมอนเพื่อให้แน่ใจว่าได้/dev/randomรับการเติมเงินบนเซิร์ฟเวอร์ที่ไม่มีหัวคุณต้องการอะไรแบบนี้เพื่อสร้างเอนโทรปีที่ต้องการ การโทรของฉันไปถึงSecureRandomตอนนี้อาจใช้เวลาเป็นมิลลิวินาที


4
การติดตั้ง apt-get hasged จากนั้น update-rc.d hasged ค่าเริ่มต้น
Rod Lima

11

หากคุณต้องการการสุ่มที่ "เข้ารหัสลับ" อย่างแท้จริงคุณต้องมีแหล่งเอนโทรปีที่แข็งแกร่ง /dev/randomช้าเพราะต้องรอให้กิจกรรมของระบบรวบรวมเอนโทรปี (อ่านดิสก์แพ็กเก็ตเครือข่ายการเคลื่อนไหวของเมาส์การกดปุ่มเป็นต้น)

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

หาก HRNG ไม่พร้อมใช้งานในระบบของคุณและคุณยินดีที่จะเสียสละความแข็งแกร่งของเอนโทรปีสำหรับการปฏิบัติงานคุณจะต้องการเมล็ด PRNG ที่ดีพร้อมข้อมูลจาก/dev/randomและให้ PRNG ทำงานเป็นกลุ่ม มีรายการของ PRNG ที่ได้รับการอนุมัติโดย NIST หลายรายการใน SP800-90ซึ่งตรงไปตรงมาเพื่อนำไปใช้


จุดดี แต่รหัสของฉันเป็นส่วนหนึ่งของแอปพลิเคชันเชิงพาณิชย์ ฉันไม่สามารถควบคุมสภาพแวดล้อมเซิร์ฟเวอร์ได้ ฉันคิดว่าเซิร์ฟเวอร์เป้าหมายนั้นไม่มีเม้าส์และคีย์บอร์ดอยู่ตลอดและพึ่งพาดิสก์และ I / O เครือข่ายทั้งหมดสำหรับเอนโทรปีซึ่งอาจเป็นปัญหาหลัก
David G

3
ฉันค้นพบว่า / dev / random ขึ้นอยู่กับเหตุการณ์ของระบบดังนั้นเพื่อเป็นการแก้ปัญหาชั่วคราวฉันเพิ่งเลื่อนเมาส์ไปมาระหว่างการทดสอบวิ่ง ....
David K

82802 ฮับสำหรับชิปเซ็ต i820 นั้นช้ามาก (RIP) ฉันประหลาดใจที่คุณสามารถรวบรวมสิ่งที่มีประโยชน์จากมัน ฉันคิดว่าฉันใช้เวลาในการบล็อกมากกว่าการรวบรวมอ็อกเท็ต
jww

6

เมื่อใช้ Java 8 ฉันพบว่าการโทรบน Linux SecureRandom.getInstanceStrong()จะให้NativePRNGBlockingอัลกอริทึมแก่ฉัน สิ่งนี้มักจะบล็อกเป็นเวลาหลายวินาทีเพื่อสร้างเกลือสองสามไบต์

ฉันเปลี่ยนเป็นการขออย่างชัดเจนNativePRNGNonBlockingแทนและตามที่คาดไว้จากชื่อจะไม่ถูกบล็อกอีกต่อไป ฉันไม่รู้ว่าสิ่งนี้เกี่ยวข้องกับความปลอดภัยอย่างไร สมมุติว่าเวอร์ชั่นที่ไม่มีการบล็อกไม่สามารถรับประกันปริมาณเอนโทรปีที่ใช้

อัปเดต : โอเคฉันพบคำอธิบายที่ยอดเยี่ยมนี้

new SecureRandom()สรุปเพื่อหลีกเลี่ยงการปิดกั้นการใช้งาน การใช้งานนี้ซึ่งจะไม่ปิดกั้นและเป็นพื้นเป็นที่ปลอดภัย/dev/urandom /dev/randomจากการโพสต์: "เวลาเดียวที่คุณต้องการเรียก / dev / random คือเมื่อเครื่องเริ่มบูทครั้งแรกและเอนโทรปียังไม่ได้สะสม"

SecureRandom.getInstanceStrong() มอบ RNG ที่แข็งแกร่งที่สุดให้คุณ แต่ปลอดภัยที่จะใช้ในสถานการณ์ที่การบล็อกจำนวนมากไม่มีผลกับคุณ


1
ฉันอนุญาตให้ getInstanceStrong()ใช้กับคีย์ระยะยาวเท่านั้นเช่นรหัส TLS และถึงอย่างนั้นฉันก็อยากจะใช้new SecureRandom()หรือเครื่องกำเนิดคีย์คู่ที่เข้ากันได้กับ FIPS หรือเครื่องสร้างตัวเลขสุ่ม ใช่แล้วนี่เป็นคำตอบถ้า /dev/urandomไม่บล็อก: ในที่สุดมันก็ยังต้องอาศัยระบบเอนโทรปีหลังจากทั้งหมด แต่โดยทั่วไปแล้วมันเป็นคำแนะนำที่ดีมาก หาก/dev/urandomบล็อกคุณอาจต้องแก้ไขแหล่งที่มาของปัญหาแทนแอปพลิเคชัน Java ของคุณ
Maarten Bodewes

5

มีเครื่องมือ (อย่างน้อยบน Ubuntu) ที่จะดึงข้อมูลแบบสุ่มเข้าสู่ระบบของคุณ คำสั่งนั้นเรียบง่าย:

rngd -r /dev/urandom

และคุณอาจต้องการ sudo ที่ด้านหน้า หากคุณไม่มีแพ็คเกจ rng-tools คุณจะต้องติดตั้ง ฉันลองสิ่งนี้และมันช่วยฉันได้อย่างแน่นอน!

ที่มา: matt vs world


2
สิ่งนี้ค่อนข้างอันตรายเพราะมันปิดการประมาณการเอนโทรปีของเคอร์เนลทั้งระบบ ฉันคิดว่าเพื่อจุดประสงค์ในการทดสอบ (อ่าน: เจนกินส์ใช้งาน Testuite ของแอป) โดยใช้ /dev/./urandom เป็นเรื่องปกติ แต่ในการผลิตมันไม่ใช่
mirabilos

นี่เป็นทางออกเดียวที่ได้ผลสำหรับฉัน ฉันมีปัญหา“ เอนโทรปีไม่เพียงพอ” เมื่อสร้างโครงการ Android ด้วย Gradle บน Jenkins CI และการส่งพารามิเตอร์ไปที่การสร้างไม่ได้ช่วยอะไร
ชาวสลาฟ

ฉันต้องรวมsudo rngd -r /dev/urandomกับsudo apt install rng-toolsxenial
MrMesees

5

ผมประสบเดียวกันปัญหา หลังจากที่บาง Googling กับคำค้นหาที่ถูกต้องฉันมาข้ามบทความนี้ดีในDigitalOcean

hasged เป็นโซลูชั่นที่มีศักยภาพโดยไม่ลดทอนความปลอดภัย

ฉันแค่อ้างถึงส่วนที่เกี่ยวข้องจากบทความที่นี่

ตามหลักการ HAVEGE และก่อนหน้านี้อ้างอิงไลบรารีที่เชื่อมโยงได้อนุญาตให้สร้างการสุ่มขึ้นอยู่กับความแปรผันของเวลาประมวลผลโค้ดในโปรเซสเซอร์ เนื่องจากเกือบจะเป็นไปไม่ได้ที่โค้ดหนึ่งชิ้นจะใช้เวลาในการดำเนินการที่แน่นอนแม้ในสภาพแวดล้อมเดียวกันบนฮาร์ดแวร์เดียวกันเวลาของการรันโปรแกรมเดี่ยวหรือหลายโปรแกรมจึงควรเหมาะสมกับแหล่งที่มาแบบสุ่ม การใช้งานแบบแยกส่วนได้รวบรวมแหล่งที่มาแบบสุ่มของระบบของคุณ (โดยปกติ / dev / สุ่ม) โดยใช้ความแตกต่างในตัวนับเวลาของตัวประมวลผล (TSC) ของตัวประมวลผลของคุณหลังจากเรียกใช้ลูปซ้ำ ๆ

ติดตั้งอย่างไร

ทำตามขั้นตอนในบทความนี้ https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

ฉันโพสต์ไว้ที่นี่


5

ปัญหาที่คุณอ้างถึง/dev/randomไม่ได้เกิดจากSecureRandomอัลกอริธึม แต่เป็นแหล่งที่มาของการสุ่มที่ใช้ ทั้งสองเป็นมุมฉาก คุณควรจะรู้ว่าหนึ่งในสองนั้นกำลังทำให้คุณช้าลง

หน้าคณิตศาสตร์ผิดปกติที่คุณเชื่อมโยงกล่าวอย่างชัดเจนว่าพวกเขาไม่ได้กล่าวถึงแหล่งที่มาของการสุ่ม

คุณสามารถลองใช้ผู้ให้บริการ JCE ที่แตกต่างกันเช่น BouncyCastle เพื่อดูว่าการใช้งานของพวกเขาSecureRandomนั้นเร็วกว่าหรือไม่

การค้นหาสั้น ๆยังเผยให้เห็นแพตช์ Linux ที่แทนที่การใช้งานเริ่มต้นด้วย Fortuna ฉันไม่รู้อะไรมากเกี่ยวกับสิ่งนี้ แต่คุณสามารถตรวจสอบได้

ฉันควรจะพูดถึงว่าในขณะที่มันอันตรายมากที่จะใช้ดำเนินการไม่ดีSecureRandomขั้นตอนวิธีการและ / หรือแหล่งสุ่มคุณสามารถม้วนของผู้ให้บริการ JCE SecureRandomSpiของคุณเองด้วยการดำเนินงานที่กำหนดเอง คุณจะต้องผ่านกระบวนการกับซันเพื่อให้ผู้ให้บริการลงนาม แต่จริงๆแล้วมันค่อนข้างตรงไปตรงมา พวกเขาเพียงต้องการให้คุณส่งแฟกซ์แบบฟอร์มโดยระบุว่าคุณรับรู้ถึงข้อ จำกัด การส่งออกของสหรัฐฯในไลบรารี crypto


ผู้ให้บริการ JCE ที่แตกต่างกันเหล่านี้มีการใช้งานก็ต่อเมื่อใช้แหล่งข้อมูลอื่นของเอนโทรปีซึ่งโดยทั่วไปหมายความว่าพวกเขาต้องใช้ฮาร์ดแวร์เฉพาะเช่น HSM มิฉะนั้นพวกเขาก็มีแนวโน้มที่จะได้สัมผัสกับการชะลอตัวขึ้นอยู่กับปริมาณเอนโทรปีที่พวกเขาสกัดจากระบบ
Maarten Bodewes

3

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

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

ตรวจสอบให้แน่ใจว่าได้รีเฟรชในตอนนี้และจากนั้นสุ่มปลอดภัยที่ใช้สำหรับการเริ่มต้นตัวอย่างเช่นคุณอาจมีหนึ่งสุ่มปลอดภัยที่สร้างขึ้นต่อลูกค้าโดยใช้หนึ่งเครื่องกำเนิดไฟฟ้าแบบสุ่มปลอม mersenne twister หลอกต่อลูกค้าได้รับการสุ่มสูงพอ


2
คำตอบนี้ผิด: Twers Mersenne ไม่ใช่ผู้สร้างหมายเลขสุ่มที่ปลอดภัย มันจะเป็นขั้นตอนวิธีการที่ดีสำหรับการแต่ไม่ได้สำหรับRandom SecureRandom
Maarten Bodewes

3

ตามเอกสารประกอบอัลกอริทึมที่แตกต่างกันที่ใช้โดย SecureRandom คือตามลำดับของการตั้งค่า:

  • บนระบบ * NIX ส่วนใหญ่
    1. NativePRNG
    2. SHA1PRNG
    3. NativePRNGBlocking
    4. NativePRNGNonBlocking
  • บนระบบ Windows
    1. SHA1PRNG
    2. ใช้ Windows PRNG

เมื่อคุณถามเกี่ยวกับ Linux ฉันจะเพิกเฉยต่อการติดตั้ง Windows และ SunPKCS11 ซึ่งมีเฉพาะใน Solaris เท่านั้นเว้นแต่คุณจะติดตั้งด้วยตัวคุณเองแล้วคุณจะไม่ถามคำถามนี้

ตามเอกสารเดียวกันเหล่านั้นขั้นตอนวิธีการเหล่านี้ใช้คืออะไร

SHA1PRNG การ
เริ่มต้นเริ่มต้นทำได้ในขณะนี้ผ่านการรวมกันของคุณสมบัติของระบบและอุปกรณ์รวบรวมเอนโทรปีของ java.security

NativePRNG
nextBytes()ใช้การ/dev/urandom
generateSeed()ใช้งาน/dev/random

NativePRNGBlocking
nextBytes()และการgenerateSeed()ใช้งาน/dev/random

NativePRNGNon การล็อค
nextBytes()และการgenerateSeed()ใช้งาน/dev/urandom

ซึ่งหมายความว่าถ้าคุณใช้SecureRandom random = new SecureRandom()มันจะลงรายการนั้นจนกว่าจะพบรายการที่ใช้งานได้ซึ่งโดยทั่วไปจะเป็น NativePRNG และนั่นหมายความว่ามันเมล็ดตัวเองจาก/dev/random(หรือใช้ว่าถ้าคุณสร้างเมล็ดอย่างชัดเจน) จากนั้นใช้/dev/urandomสำหรับการรับไบต์ถัดไป, ints, double, booleans สิ่งที่มีคุณ

เนื่องจาก/dev/randomกำลังบล็อก (จะบล็อกจนกว่าจะมีเอนโทรปีเพียงพอในพูลเอนโทรปี) ซึ่งอาจขัดขวางประสิทธิภาพการทำงาน

วิธีแก้ปัญหาหนึ่งที่ใช้สิ่งที่ต้องการได้สร้างเอนโทรปีเพียงพอโซลูชั่นอื่นใช้/dev/urandomแทน ในขณะที่คุณสามารถตั้งค่าว่าสำหรับ JVM ทั้งเป็นทางออกที่ดีจะทำมันเช่นนี้เฉพาะโดยใช้SecureRandom SecureRandom random = SecureRandom.getInstance("NativePRNGNonBlocking")โปรดทราบว่าวิธีการที่สามารถโยน NoSuchAlgorithmException ถ้า NativePRNGNonBlocking ดังนั้นได้เตรียมที่จะย้อนกลับไปเริ่มต้น

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

นอกจากนี้ทราบว่าในระบบระวัง * อื่น ๆอาจจะทำงานแตกต่างกัน/dev/urandom


คือ/dev/urandomสุ่มเพียงพอหรือไม่

ภูมิปัญญาดั้งเดิมมีเพียงว่ามัน/dev/randomสุ่มพอ อย่างไรก็ตามเสียงบางอย่างแตกต่างกัน ใน"วิธีที่ถูกต้องในการใช้ SecureRandom"และ"Myths about / dev / urandom"เป็นที่ถกเถียงกันอยู่ว่า/dev/urandom/ดี

ผู้ใช้มากกว่าในการรักษาความปลอดภัยข้อมูลสแต็คเห็นด้วยกับที่ โดยทั่วไปถ้าคุณต้องถาม/dev/urandomก็ดีสำหรับวัตถุประสงค์ของคุณ


2

ฉันไม่ได้ตีกับปัญหานี้ด้วยตัวเอง แต่ฉันจะวางไข่ที่จุดเริ่มต้นโปรแกรมซึ่งพยายามสร้างเมล็ดทันทีจากนั้นก็ตาย วิธีการที่คุณเรียกใช้ randoms จะเข้าร่วมกับเธรดนั้นถ้ายังมีชีวิตอยู่ดังนั้นการเรียกครั้งแรกจะบล็อกเฉพาะถ้ามันเกิดขึ้นเร็วมากในการเรียกใช้โปรแกรม


มันค่อนข้างแฮ็คมาก แต่มันอาจใช้งานได้ ไม่ได้กล่าวว่า PRNG ที่ใช้แล้วอาจไม่ใช้วัสดุเมล็ดเพิ่มเติมซึ่งยังอาจนำไปสู่การบล็อก ควรใช้หมายเลขสุ่มที่แตกต่างกันในการจัดเตรียมหรือแก้ไขเอนโทรปีในระบบ อย่างน้อยก็อาจเป็นวิธีแก้ปัญหาชั่วคราวฉันไม่ได้ลงคะแนนเลยคำตอบ
Maarten Bodewes

2

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

อย่าประนีประนอมกับการสร้างตัวเลขสุ่ม จุดอ่อนที่ทำให้ความปลอดภัยของคุณลดลง

ฉันไม่เห็นเครื่องกำเนิดไฟฟ้าแบบปรมาณู COTS จำนวนมาก แต่มีหลายแผนสำหรับพวกเขาหากคุณต้องการข้อมูลสุ่มจำนวนมาก เว็บไซต์หนึ่งที่มีสิ่งที่น่าสนใจให้ดูเสมอรวมถึง HotBits คือJohn Walker's Fourmilab


1
ฉันสงสัยอยู่เสมอเกี่ยวกับเรื่องนี้เนื่องจากผลิตภัณฑ์ที่เสื่อมโทรมของ Hadronic เกือบจะบรรลุถึงอุดมคติของแหล่งที่มาแบบสุ่มฉันไม่สามารถกำจัดความปรารถนาของฉันที่จะใช้สิ่งนั้นมากกว่าเครื่องมืออัลกอริธึม สำหรับจุดประสงค์ของ op ฉันได้ตัดสินใจเมื่อนานมาแล้วว่าเวลาส่วนหน้านั้นเกิดจากเครื่องมือรักษาความปลอดภัยทั้งหมด ถ้าใครจะต้องใช้ตัวสุ่มที่สามารถเรียกได้ในตัวสร้างและเพียงจำไว้ว่าต้องสร้างหนึ่งตัวในเวลาที่โหลดหน้ามันจะถูกฝังอยู่ภายใต้การแลกเปลี่ยน avl-in และแม้จู้จี้จุกจิกในขณะที่ฉันไม่ได้สังเกตเห็น
นิโคลัสจอร์แดน

ชิปเซ็ต Intel 8xx (และอื่น ๆ อีกมากมาย) มีฮาร์ดแวร์ RNG ที่ใช้สัญญาณรบกวนความร้อนซึ่งเป็นผลกระทบควอนตัมที่คาดเดาไม่ได้อย่างแท้จริง โมดูลแพลตฟอร์มที่เชื่อถือได้สามารถมีฮาร์ดแวร์ RNG ด้วยเช่นกัน แต่น่าเสียดายที่แล็ปท็อปของฉันไม่มี
เอริก

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

@MaartenBodewes นั่นเป็นจุดที่ดี หากการนำไปใช้นั้นเป็นสิ่งที่บล็อกรอเอนโทรปีของระบบฉันคิดว่าการใช้งานมันเป็นซิงเกิลตันในแอปพลิเคชันของคุณไม่ใช่ความคิดที่น่ากลัวเพราะแหล่งข้อมูลพื้นฐานนั้นมีประสิทธิภาพเพียงหนึ่งเดียว แต่การใช้อินสแตนซ์หนึ่งในการเพาะเมล็ดพันธุ์อื่นเป็นข้อเสนอแนะที่ดีแม้ว่าจะซับซ้อน ฉันไม่แน่ใจ แต่ฉันคิดว่าผู้ให้บริการของ Sun (และจากนั้น Oracle) SecureRandomได้เปลี่ยนสองครั้งในช่วง 10 ปีที่ผ่านมาในการรวบรวมเอนโทรปี
erickson

ฉันแน่ใจว่ามันมีการเปลี่ยนแปลงหลายครั้งมากดังนั้นฉันจะไม่พยายามและใส่การเปลี่ยนแปลงทั้งหมดในความคิดเห็นนี้ :) มีโอกาสน้อยที่ความล่าช้าSecureRandomยังคงเป็นปัญหาอยู่ แต่เอนโทรปีที่ต่ำในระบบจะเป็นปัญหาเสมอ การใช้ซิงเกิลตันจะสร้างรหัสคู่ที่แข็งแกร่งซึ่งเป็นรูปแบบการต่อต้านการออกแบบ ดังนั้นจึงควรใช้ด้วยความระมัดระวังอย่างยิ่ง คุณควรจะต้องย้อนกลับการอ้างอิงทั้งหมดในรหัสถ้าคุณจะแก้ไขปัญหา
Maarten Bodewes

2

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

หากคุณไม่ต้องการการรับประกันแบบสุ่มเต็มรูปแบบอาจมีการแลกเปลี่ยนประสิทธิภาพที่เหมาะสม ฉันมักจะเห็นด้วยกับคำตอบของ Dan Dyerเกี่ยวกับ AESCounterRNG จาก Uncommons-Maths หรือ Fortuna (หนึ่งในผู้แต่งคือ Bruce Schneier ผู้เชี่ยวชาญในวิทยาการเข้ารหัส) ฉันไม่เคยใช้อย่างใดอย่างหนึ่ง แต่ความคิดที่ปรากฏมีชื่อเสียงได้อย่างรวดเร็วก่อน

ฉันจะ คิดว่าถ้าคุณสามารถสร้างเมล็ดเริ่มต้นสุ่มเป็นระยะ ๆ (เช่นวันละครั้งหรือชั่วโมงหรืออะไรก็ตาม) คุณสามารถใช้รหัสกระแสเร็วเพื่อสร้างตัวเลขสุ่มจากชิ้นต่อเนื่องของกระแส (ถ้ากระแสตัวเลขใช้ XOR เพียงแค่ ผ่านในกระแสของค่า null หรือคว้าบิต XOR โดยตรง) eStream ของECRYPTโครงการมีข้อมูลที่ดีมากมายรวมถึงการวัดประสิทธิภาพ สิ่งนี้จะไม่รักษาเอนโทรปีระหว่างจุดที่คุณเติมใหม่ดังนั้นถ้ามีคนรู้หนึ่งในตัวเลขสุ่มและอัลกอริทึมที่คุณใช้เทคนิคอาจเป็นไปได้ด้วยกำลังการคำนวณจำนวนมากเพื่อทำลายการเข้ารหัสและ เดาสถานะภายในของมันเพื่อให้สามารถทำนายตัวเลขสุ่มในอนาคต แต่คุณต้องตัดสินใจว่าความเสี่ยงและผลที่ตามมานั้นเพียงพอที่จะพิสูจน์ค่าใช้จ่ายในการรักษาเอนโทรปีหรือไม่

แก้ไข: นี่คือบางส่วนของหลักสูตรการเข้ารหัสลับใน RNG ที่ฉันพบใน 'สุทธิที่มีความเกี่ยวข้องกับหัวข้อนี้มาก


1
"Fortuna (หนึ่งในนักเขียนที่เป็นบรูซ Schneier ผู้เชี่ยวชาญในการเข้ารหัส)" - และอีกคนหนึ่งคือนีลส์เฟอร์กูสันเป็นผู้เชี่ยวชาญในการเข้ารหัส :-)
สตีฟเจสซอพ

2

หากฮาร์ดแวร์ของคุณรองรับลองใช้ Java RdRand Utilityซึ่งฉันเป็นผู้เขียน

เป็นไปตามRDRANDคำสั่งของ Intel และเร็วกว่าประมาณ 10 เท่าSecureRandomและไม่มีปัญหาเกี่ยวกับแบนด์วิดท์สำหรับการใช้งานในปริมาณมาก


โปรดทราบว่าการติดตั้งนี้ใช้งานได้เฉพาะกับซีพียูเหล่านั้นที่ให้คำแนะนำ (เช่นเมื่อrdrandตั้งค่าตัวประมวลผล) คุณต้องสร้างอินสแตนซ์ของมันผ่านตัวRdRandRandom()สร้าง ไม่มีProviderการใช้งานที่เฉพาะเจาะจง


3
คุณอาจต้องการที่จะอ่านpeople.umass.edu/gbecker/BeckerChes13.pdfและให้แน่ใจว่าไม่เคยใช้เพียงข้อมูล Intel RDRAND เสมอผสมกับข้อมูลที่คาดเดาไม่ได้อื่น ๆ เช่นเอาท์พุทของการเข้ารหัสกระแส aRC4 (เมล็ดจาก / dev / urandom และกับไม่กี่ KiB แรกของการส่งออกโยนออกไปสำหรับอคติที่รู้จักกัน)
mirabilos

+1 mirabilos ฉันคิดว่าRDRANDเป็นแหล่งข้อมูลที่ดี แต่ไม่น่าเชื่อถือเลย แน่นอนว่ามันจะต้องเป็นหนึ่งในหลาย ๆ ปัจจัยในการสะสม (ไม่ผิดกับเดวิดจอห์นสตัน)
jww

ฉันโหวตแล้วแก้ไขลิงก์และให้ข้อมูลพื้นหลังบางอย่าง หากคุณไม่เห็นด้วยโปรดย้อนกลับการแก้ไข
Maarten Bodewes

1

สิ่งอื่นที่ควรดูคือคุณสมบัติ securerandom.source ในไฟล์ lib / security / java.security

อาจมีประโยชน์ด้านประสิทธิภาพการใช้ / dev / urandom มากกว่า / dev / random โปรดจำไว้ว่าหากคุณภาพของตัวเลขสุ่มมีความสำคัญอย่าทำให้ความปลอดภัยลดลง

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