קטגוריה ב-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 ואילך או
אפשר לחסום את ה-thread, צריך לחכות עד שיצטברו מספיק אנטרופיה
יוצרים את המספרים האקראיים (כלומר משתמשים ב-/dev/random
). כדי לעשות את זה, צריך להתקשר
getInstanceStrong()
:
Kotlin
val rand = SecureRandom.getInstanceStrong()
Java
SecureRandom rand = SecureRandom.getInstanceStrong();
אחרת, בגרסאות הליבה של Linux שקדמו ל-5.17, כשאי אפשר לחסום את השרשור בזמן יצירת מספרים אקראיים, צריך לקרוא ישירות למבנה 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
- Predictable Seed CWE
- PRNG CWE חלש מבחינה קריפטוגרפית
- Java Secure Random
- Java Random לעומת SecureRandom
- איך משתמשים ב-SecureRandom
- הנחיות אבטחה ל-PRNG ב-Python
- OWASP Cryptographic Storage Cheat Sheet
- CVE-2013-6386: Weak PRNG vuln ב-Drupal
- CVE-2006-3419: נקודת חולשה של PRNG חלש ב-Tor
- CVE-2008-4102: ערך בסיס צפוי ב-Joomla
- תיקון אקראי לליבה של Linux