ตัวเลือก java.security.egd นั้นใช้ทำอะไร


22

ในโครงการที่ฉันกำลังดำเนินการแอปพลิเคชันจะเปิดตัวโดยใช้คำสั่งที่คล้ายกับสิ่งนี้:

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

ฉันไม่เคยเห็นjava.security.egdตัวเลือกมาก่อน ดูเหมือนว่าจะใช้การกำหนดค่าการสร้างตัวเลขสุ่มในแอปพลิเคชัน Java

ถูกต้องหรือไม่ ควรใช้เมื่อใด

คำตอบ:


29

แอ็พพลิเคชัน Java สามารถและควรใช้คลาสjava.security.SecureRandomเพื่อสร้างค่าสุ่มที่แข็งแกร่งของการเข้ารหัสลับโดยใช้ตัวสร้างตัวเลขสุ่ม ( CSPRNG ) แบบเข้ารหัสลับแบบเข้ารหัสลับที่เข้ารหัสลับ การใช้งาน JDK มาตรฐานของคลาสjava.util.Randomจะไม่ถือว่าเป็น cryptographically strong

ระบบปฏิบัติการแบบ Unix มี/dev/randomไฟล์พิเศษที่ให้บริการหมายเลขสุ่มหลอกที่มีเสียงรบกวนจากสิ่งแวดล้อมซึ่งรวบรวมจากไดรเวอร์อุปกรณ์และแหล่งอื่น ๆ แต่มันบล็อกถ้ามีเอนโทรปีน้อยลงกว่าที่ร้องขอ ; /dev/urandomโดยทั่วไปแล้วจะไม่มีทางปิดกั้นแม้ว่าเมล็ดพันธุ์ตัวสร้างหมายเลขเทียมเทียมก็ไม่ได้เริ่มต้นอย่างสมบูรณ์ด้วยเอนโทรปีตั้งแต่เริ่มระบบ ยังคงมีไฟล์พิเศษลำดับที่ 3 /dev/arandomซึ่งบล็อกหลังจากบูตจนกว่าเมล็ดจะได้รับการเริ่มต้นอย่างปลอดภัยด้วยเอนโทรปีเพียงพอและจากนั้นจะไม่บล็อกอีกครั้ง

โดยค่าเริ่มต้นเมล็ด JVM ที่SecureRandomระดับการใช้/dev/randomดังนั้น รหัสของคุณ Java สามารถป้องกันโดยไม่คาดคิด ตัวเลือก-Djava.security.egd=file:/dev/./urandomในการเรียกใช้บรรทัดคำสั่งที่ใช้เพื่อเริ่มกระบวนการ Java จะบอกให้ JVM ใช้/dev/urandomแทน

สิ่งพิเศษที่/./ดูเหมือนว่าจะทำให้ JVM ใช้อัลกอริทึม SHA1PRNGซึ่งใช้ SHA-1 เป็นรากฐานของ PRNG (Pseudo Random Number Generator) มันแข็งแกร่งกว่าอัลกอริทึม NativePRNG ที่ใช้เมื่อ/dev/urandomมีการระบุ

ในที่สุดก็มีตำนานว่า/dev/urandomเป็นหลอกเครื่องกำเนิดไฟฟ้าจำนวนสุ่ม PRNG ขณะที่/dev/randomเป็น“ของจริง” เครื่องกำเนิดไฟฟ้าจำนวนสุ่ม สิ่งนี้ไม่เป็นความจริงทั้งคู่/dev/randomและ/dev/urandomถูกป้อนด้วย CSPRNG เดียวกัน (เครื่องสร้างหมายเลขปลอมเทียมแบบเข้ารหัสลับ) เฉพาะพฤติกรรมเมื่อสระว่ายน้ำของพวกเขาหมดเอนโทรปีตามการประมาณการบางอย่างแตกต่าง: /dev/randomบล็อกในขณะที่/dev/urandomไม่

แล้วเอนโทรปีทำงานต่ำแค่ไหน? มันไม่สำคัญ

ปรากฎว่า "ดูสุ่ม" เป็นข้อกำหนดขั้นพื้นฐานสำหรับการสร้างแบบเข้ารหัสจำนวนมากของเรา และถ้าคุณรับเอาท์พุทของแฮชการเข้ารหัสมันจะต้องแยกไม่ออกจากสตริงการสุ่มเพื่อที่ยันต์จะยอมรับมัน นั่นเป็นเหตุผลของการใช้อัลกอริทึม SHA1PRNG เนื่องจากใช้ฟังก์ชันแฮชและตัวนับพร้อมกับเมล็ด

ควรใช้เมื่อใด

ฉันจะบอกเสมอ

แหล่งที่มา:
https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom


แก้ไข 04/2020:

ความคิดเห็นกล่าวถึงการเปลี่ยนแปลงพฤติกรรมของระดับSecureRandomใน Java 8

SHA1PRNG และ NativePRNG ได้รับการแก้ไขเพื่อให้สอดคล้องกับคุณสมบัติแหล่งที่มาของเมล็ด SecureRandom ในไฟล์ java.security (วิธีแก้ปัญหาที่คลุมเครือโดยใช้ไฟล์: /// dev / urandom และ file: / dev /./ urandom ไม่จำเป็นอีกต่อไป)

สิ่งนี้ได้รับการชี้ให้เห็นแล้วจากการทดสอบที่อ้างถึงในส่วนแหล่งข้อมูลด้านบน /./จำเป็นต้องมีการเพิ่มเติมเพื่อเปลี่ยนอัลกอริทึมที่ใช้โดยSecureRanomใน Java 8 จาก NativePRNG เป็น SHA1PRNG

อย่างไรก็ตามฉันมีข่าวบางอย่างที่ฉันต้องการแบ่งปัน เป็นต่อJEP-273ตั้งแต่ Java 9 SecureRandomการดำเนินการระดับสามบิตตายตัว Generator สุ่ม (DRBG)กลไกที่อธิบายไว้ในNIST 800-90Ar1 กลไกเหล่านี้ใช้อัลกอริธึมที่ทันสมัยเช่นเดียวกับ SHA-512 และ AES-256

JDK มีการใช้งานSecureRandomสองประเภท:

  • หนึ่งคือขึ้นอยู่กับแพลตฟอร์มและขึ้นอยู่กับการโทรพื้นเมืองหรืออุปกรณ์ OS เช่นการอ่าน/dev/{u}randomบน Unix หรือการใช้ CryptoAPI บน Windows รุ่นล่าสุดของ Linux และ Windows แล้วสนับสนุน DRBG, แต่รุ่นเก่าและระบบฝังตัวอาจจะไม่
  • อีกประเภทหนึ่งคือการใช้งานจาวาบริสุทธิ์ซึ่งใช้การใช้งาน RNG แบบเก่าที่ใช้ SHA1 ซึ่งไม่รุนแรงเท่ากับอัลกอริทึมที่ใช้โดยกลไก DRBG ที่ได้รับอนุมัติ

ในขณะเดียวกันคู่มือ Java 13 การรักษาความปลอดภัยของนักพัฒนายังคงอ่าน

บน Linux และ macOS หากอุปกรณ์การรวบรวมเอนโทรปีใน java.security ถูกตั้งค่าเป็นfile:/dev/urandomหรือแสดงfile:/dev/randomว่าต้องการ NativePRNG เป็น SHA1PRNG มิฉะนั้นแนะนำให้ใช้ SHA1PRNG

เพื่อให้ชัดเจนว่ากลไก DRBG ใหม่ทำงานร่วมกับ PRNG ก่อนหน้านี้ได้อย่างไรฉันจึงทำการทดสอบบน macOS (ดาร์วิน) ด้วย AdoptOpenJDK (build 13.0.2 + 8) นี่คือผลลัพธ์:

ไฟล์: / dev / random
ลำดับความพึงพอใจสำหรับผู้ให้บริการ:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

ไฟล์: / dev / urandom
ลำดับการตั้งค่าสำหรับผู้ให้บริการ:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

ไฟล์: / dev /./ urandom
ลำดับการตั้งค่าสำหรับผู้ให้บริการ:

SecureRandom.DRBG
SecureRandom.SHA1PRNG
SecureRandom.NativePRNG

สรุป:

ฉันขอแนะนำให้ใช้-Djava.security.egd=file:/dev/./urandomเพื่อให้แน่ใจว่าใช้ประโยชน์จากการใช้งานSecureRandom ที่แข็งแกร่งที่สุดโดยไม่คำนึงถึงแพลตฟอร์มที่ใช้ในขณะที่หลีกเลี่ยงการบล็อกรหัสโดยไม่คาดคิด


1
ในฐานะของ Java 8, "obscure workaround" ของส่วนเสริม. / ในชื่อไฟล์นั้นไม่จำเป็นต้องใช้อีกต่อไปดังนั้นคุณสามารถใช้ "/ dev / urandom", ดู: docs.oracle.com/javase/8/docs / technotes / ไกด์ / ความปลอดภัย / …
Kamal

ขอบคุณสำหรับการอัปเดตคำตอบ (โดยเฉพาะเกี่ยวกับการเปลี่ยนแปลงใน Java 9 และ 13) ตามความเข้าใจของฉันในฐานะของ Java 8 การตั้งค่า "อุปกรณ์รวบรวมเอนโทรปี" เป็น / dev / urandom หรือ /dev/./urandom ควรให้ผลลัพธ์เดียวกันแน่นอนมิฉะนั้นการแก้ไขจะไม่สมเหตุสมผล จากเปอร์สเปคทีฟของระบบปฏิบัติการชี้ไปที่ไฟล์ที่เหมือนกันดังนั้นจึงไม่ควรส่งผลกระทบต่อ Java (เกิดขึ้นก่อนการแก้ไข แต่นั่นเป็นข้อผิดพลาดไม่ใช่คุณสมบัติที่ตั้งใจไว้) ดังนั้นคำสั่งของคุณ "/./ พิเศษจะต้องมีผลต่อการเลือก PRNG" ไม่ควรเป็นจริงอีกต่อไปตั้งแต่วันที่ Java 8
Kamal

ขอบคุณ @Kal สำหรับความคิดเห็นของคุณ วลีก่อนหน้าของฉัน "การเลือก PRNG" ไม่ชัดเจนเพียงพอ ฉันได้ใช้ถ้อยคำใหม่เพื่อชี้แจงว่าฉันกำลังพูดถึงอัลกอริทึมที่ใช้: NativePRNG หรือ SHA1PRNG การใช้การ/dev/urandomเลือก NativePRNG ที่ป้อนโดย/dev/urandomในขณะที่/dev/./urandomหยิบ SHA1PRNG ขึ้นมา (เช่นการป้อนด้วย/dev/urandom) เมื่อใช้ Java 8 จาก Java 9 เป็นต้นไป DRBG จะมีความสำคัญกว่าเมื่อ/dev/./urandomมีการระบุแหล่งที่มา
dbaltor

1

ไม่จำเป็นต้องใช้อีกต่อไปหากคุณใช้ JDK 8 หรือสูงกว่า

ปัญหาได้รับการแก้ไขโดย Java และนี่คือลิงค์บางส่วน

เค้าโครง

SHA1PRNG และ NativePRNG ได้รับการแก้ไขเพื่อให้สอดคล้องกับคุณสมบัติแหล่งที่มาของเมล็ด SecureRandom ในไฟล์ java.security (วิธีแก้ปัญหาที่คลุมเครือโดยใช้ไฟล์: /// dev / urandom และ file: / dev /./ urandom ไม่จำเป็นอีกต่อไป)

สำหรับข้อมูลเพิ่มเติม (ค้นหาแบบสุ่มในหน้า):

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


ฉันไม่เชื่อว่าสิ่งนี้ถูกต้อง สำหรับพื้นหลัง: tersesystems.com/blog/2015/12/17/…การแก้ไขใน Java 8 เพียงบอกว่าตอนนี้พวกเขาเคารพคุณสมบัติแหล่งที่มาของเมล็ด SecureRandom ในไฟล์ java.security แต่โดยค่าเริ่มต้นที่ยังมี: securerandom.source = file: / dev / random "การแก้ปัญหาชัดเจน" หมายถึงพิเศษ. / ในชื่อไฟล์ยังกล่าวถึงโดยคำตอบที่ยอมรับ (และโหวตมากที่สุด) ที่นี่
Kamal

"การแก้ปัญหาปิดบัง" ถูกต้องเฉพาะในสถานการณ์ที่เฉพาะเจาะจงดู: bugs.java.com/bugdatabase/view_bug.do?bug_id=6202721
Kamal

@Kamal ลิงก์ที่คุณโพสต์อ้างถึง Java 6 และรุ่นก่อนหน้า
Venu Madhav

นั่นคือจุดที่แน่นอนมันได้รับการแก้ไขใน Java 8 ตามรายงานข้อผิดพลาด "การแก้ปัญหาชัดเจน" (เพิ่มพิเศษ. / ในชื่อไฟล์) เป็นสิ่งจำเป็นหลังจาก Java 1.4.2 และสูงถึง 6 ฉันคิดว่า ใน Java 7 เช่นกันไม่เช่นนั้นจะไม่ได้รับการแก้ไขใน Java 8 การตั้งค่า / dev / urandom แทนที่จะเป็น / dev / random นั้นยังจำเป็นต้องใช้หากคุณต้องการใช้อุปกรณ์ที่ไม่ปิดกั้น
Kamal

0

สิ่งนี้เกี่ยวข้องกับความแตกต่างของ linux /dev/randomและตัว/dev/urandomสร้างตัวเลขสุ่ม

นำมาจากลิงค์นี้

Java Bug 6202721ระบุว่า java.security.SecureRandom ใช้ / dev / random มากกว่า / dev / urandom แม้ว่าจะมีการระบุ / dev / urandom ไว้ในขณะนั้น (ประมาณปี 2004) / dev / urandom ทำงานไม่ถูกต้อง ข้อผิดพลาดที่ไม่เคยมีการย้อนกลับตอนนี้ที่ / dev / urandom ทำงานได้ค่อนข้างดี ดังนั้นคุณต้องปลอมมันออกโดยการปิดบังการตั้งค่าโดยใช้ /dev/./urandom เพื่อบังคับให้ใช้ SHA1PRNG แทน / dev / random

เพื่อตอบคำถามของคุณ

ควรใช้เมื่อใด

จากลิงค์ข้างต้นนั้นเป็นสิ่งที่แปลกใหม่สำหรับ Java เวอร์ชัน 5 และต่อไปนี้ซึ่งเป็นผลมาจากปัญหาเกี่ยวกับ / dev / urandom บนระบบ Linux ย้อนกลับไปในปี 2004


อาจมีการพิมพ์ผิดในบทความนั้นเนื่องจาก Java Bug 6202721 ระบุว่า "นี่เป็นปัญหาถ้าเลือก / dev / urandom เนื่องจาก / dev / random ไม่ทำงานอย่างถูกต้อง" ดังนั้นข้อสรุปของคุณ "เป็นผลมาจากปัญหากับ / dev / urandom" ไม่ถูกต้อง ดูคำตอบที่ยอมรับสำหรับคำอธิบายในการเลือก / dev / urandom แทนค่าเริ่มต้น (/ dev / สุ่ม) เป็นความคิดที่ดีในกรณีส่วนใหญ่
Kamal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.