หมวดหมู่ OWASP: MASVS-CRYPTO: วิทยาการเข้ารหัสลับ
ภาพรวม
โปรแกรมสร้างตัวเลขสุ่ม (PRNG) เป็นอัลกอริทึมที่สร้าง ลำดับตัวเลขที่คาดการณ์ได้ตามค่าเริ่มต้นที่เรียกว่า seed ต ลำดับตัวเลขที่ PRNG สร้างขึ้นมีพร็อพเพอร์ตี้โดยประมาณเหมือนกับ ลำดับตัวเลขแบบสุ่มอย่างแท้จริง แต่เร็วกว่าและประหยัดในการคำนวณ ในการสร้าง
กล่าวคือ PRNG มีความน่าเชื่อถือสูงกว่า RNG แบบอ่อน (เช่น java.math.Random
) ในแง่ความสม่ำเสมอของการแจกแจงข้อมูลความผันผวน ซึ่งจำลองลำดับตัวเลขแบบสุ่มอย่างแท้จริง การสร้างตัวเลขแบบสุ่มที่แท้จริงจำเป็นต้องใช้
อุปกรณ์พิเศษและมักจะอยู่นอกขอบเขตของการพัฒนาตามปกติ ช่วงเวลานี้
เอกสารไม่ครอบคลุมการสร้างตัวเลขแบบสุ่มอย่างแท้จริง และมุ่งเน้นที่
PRNG เนื่องจากเป็นวิธีการมาตรฐานที่ใช้
ช่องโหว่ PRNG ที่อ่อนเกิดขึ้นเมื่อนักพัฒนาซอฟต์แวร์ใช้ PRNG ปกติสำหรับ จุดประสงค์ในการเข้ารหัส แทน PRNG ที่ปลอดภัยแบบเข้ารหัสลับ (CSPRNG) CSPRNG มีข้อกำหนดที่เข้มงวดกว่า และเมื่อไม่ทราบข้อมูลเมล็ดพันธุ์ ข้อมูลดังกล่าวต้องให้ข้อได้เปรียบที่ไม่สําคัญต่อผู้โจมตีในการแยกแยะลําดับเอาต์พุตออกจากลําดับแบบสุ่มจริง
ผู้โจมตีอาจเดาลำดับตัวเลขที่สร้างขึ้นได้ด้วยเมื่อใช้เมล็ดพันธุ์ที่คาดเดาได้ เช่น เมล็ดพันธุ์ที่นักพัฒนาซอฟต์แวร์เขียนโค้ดไว้อย่างเจาะจง เพื่อเริ่มต้น PRNG หรือ CSPRNG เนื่องจากผู้โจมตีสามารถเดาเมล็ดพันธุ์และคาดเดาเอาต์พุตที่ PRNG สร้างขึ้นได้
ผลกระทบ
หากมีการใช้ PRNG ที่ไม่มีการเข้ารหัสลับในบริบทด้านความปลอดภัย เช่น อาจทำให้ผู้โจมตีคาดเดาตัวเลขที่สร้างขึ้นแบบสุ่มได้ และรับสิทธิ์เข้าถึงข้อมูลหรือฟีเจอร์ที่เป็นสิทธิ์เฉพาะบุคคล
การลดปัญหา
ทั่วไป
- ใช้
java.security.SecureRandom
เมื่อมีผลกระทบด้านความปลอดภัย - ใช้
java.util.Random
สำหรับกรณีอื่นๆ - อย่าใช้
Math.random
java.security.SecureRandom
แนะนำสำหรับการใช้งานด้านความปลอดภัย หากเคอร์เนล Linux เป็นเวอร์ชัน 5.17 ขึ้นไป หรืออนุญาตให้บล็อกเธรดได้ ให้รอให้ข้อมูลสุ่มสะสมมากพอก่อนที่จะสร้างตัวเลขสุ่ม (เช่น ใช้ /dev/random
) โดยเรียกใช้ getInstanceStrong()
ดังนี้
Kotlin
val rand = SecureRandom.getInstanceStrong()
Java
SecureRandom rand = SecureRandom.getInstanceStrong();
หรือในเคอร์เนล Linux เวอร์ชันก่อน 5.17 เมื่อบล็อกเธรดเพื่อสร้างเลขสุ่มไม่ได้ คุณควรเรียกSecureRandom
คอนสตรัคเตอร์ SecureRandom
โดยตรง ดังนี้
Kotlin
import java.security.SecureRandom
object generateRandom {
@JvmStatic
fun main(args: Array<String>) {
// Create instance of SecureRandom class
val rand = SecureRandom()
// Generate random integers in range 0 to 999
val rand_int = rand.nextInt(1000)
// Use rand_int for security & authentication
}
}
Java
import java.security.SecureRandom;
public class generateRandom {
public static void main(String args[])
{
// Create instance of SecureRandom class
SecureRandom rand = new SecureRandom();
// Generate random integers in range 0 to 999
int rand_int = rand.nextInt(1000);
// Use rand_int for security & authentication
}
}
SecureRandom
ได้รับค่าตั้งต้นจาก /dev/urandom
และจะดำเนินการโดยอัตโนมัติ
ใช้เมื่อมีการสร้างหรือได้วัตถุนั้นขึ้น ดังนั้นจึงไม่จำเป็นต้อง
ตั้ง PRNG อย่างชัดเจน โดยทั่วไปแล้ว การใช้งานเชิงกำหนดของ SecureRandom
(โดยเฉพาะอย่างยิ่งถ้าวิธีนี้นำไปสู่ การฮาร์ดโค้ดค่าตั้งต้น ซึ่ง
ทุกคนที่คอมไพล์แอปจะเห็น) นักพัฒนาแอปที่ต้องการสร้างเอาต์พุตแบบสุ่มจำลองที่ซ้ำกันได้ควรใช้องค์ประกอบพื้นฐานที่เหมาะสมกว่า เช่น HMAC, HKDF และ SHAKE
java.util.Random
หลีกเลี่ยง เพื่อวัตถุประสงค์ด้านความปลอดภัย / การตรวจสอบสิทธิ์ ซึ่งใช้ได้หลายวัตถุประสงค์ ทั้งหมด
Kotlin
import java.util.Random
object generateRandom {
@JvmStatic
fun main(args: Array<String>) {
// Create instance of SecureRandom class
val rand = Random()
// Generate random integers in range 0 to 999
val rand_int = rand.nextInt(1000)
}
}
Java
import java.util.Random;
public class generateRandom {
public static void main(String args[])
{
// Create instance of Random class
Random rand = new Random();
// Generate random integers in range 0 to 999
int rand_int = rand.nextInt(1000);
}
}
แหล่งข้อมูล
- java.security.SecureRandom
- java.util.Random
- Math.random
- CWE ของเมล็ดพันธุ์ที่คาดเดาได้
- CWE ของ PRNG ที่อ่อนแอทางวิทยาการเข้ารหัสลับ
- สุ่มเพื่อความปลอดภัยของ Java
- Java Random กับ SecureRandom
- วิธีใช้ SecureRandom
- คำแนะนำด้านความปลอดภัยของ PRNG ใน Python
- ข้อมูลสรุปของ OWASP Cryptographic Storage
- CVE-2013-6386: ช่องโหว่ PRNG ที่อ่อนแอใน Drupal
- CVE-2006-3419: vuln ของ PRNG ที่อ่อนใน Tor
- CVE-2008-4102: เมล็ดพันธุ์ที่คาดเดาได้ใน Joomla
- แพตช์แบบสุ่มเคอร์เนลของ Linux