فئة OWASP: MASVS-CRYPTO: التشفير
نظرة عامة
مولّد الأرقام العشوائية الزائفة (PRNG) هو خوارزمية تنشئ تسلسلات أرقام يمكن توقّعها استنادًا إلى قيمة بداية تُعرف باسم القيمة العشوائية. ويحتوي تسلسل الأرقام الذي ينشئه مولّد الأرقام العشوائية الزائفة على الخصائص نفسها تقريبًا التي يحتوي عليها تسلسل الأرقام العشوائية الحقيقية، ولكن يكون إنشاؤه أسرع وأقل تكلفة من الناحية الحسابية.
بعبارة أخرى، توفّر مولّدات الأرقام العشوائية الزائفة ضمانات أعلى من مولّدات الأرقام العشوائية الضعيفة (مثل java.math.Random) من حيث التوزيع المتساوي للإنتروبيا، ما يحاكي تسلسلات الأرقام العشوائية الحقيقية. ويتطلّب إنشاء أرقام عشوائية حقيقية معدّات متخصّصة، وغالبًا ما يكون خارج نطاق التطوير العادي. لا يتناول هذا المستند إنشاء أرقام عشوائية حقيقية، ويركّز فقط على مولّدات الأرقام العشوائية الزائفة لأنّها المنهجية العادية المستخدَمة.
تحدث الثغرات الأمنية في مولّدات الأرقام العشوائية الزائفة الضعيفة عندما يستخدم المطوّرون مولّد أرقام عشوائية زائفة عاديًا لأغراض التشفير، بدلاً من مولّد أرقام عشوائية زائفة آمن بطريقة مشفَّرة (CSPRNG). تفرض مولّدات الأرقام العشوائية الزائفة الآمنة بطريقة مشفَّرة متطلبات أكثر صرامة، وعندما تكون القيمة العشوائية غير معروفة، يجب ألا تمنح المهاجم سوى ميزة ضئيلة في التمييز بين تسلسل الإخراج وتسلسل عشوائي فعلي.
قد يتمكّن المهاجمون أيضًا من تخمين تسلسل الأرقام الذي تم إنشاؤه عند استخدام قيم عشوائية يمكن توقّعها، مثل تلك التي تم ترميزها بشكل ثابت من قِبل المطوّر، لتهيئة مولّد أرقام عشوائية زائفة أو مولّد أرقام عشوائية زائفة آمن بطريقة مشفَّرة، لأنّه يمكن للمهاجم تخمين القيمة العشوائية وبالتالي توقّع الإخراج الذي ينشئه مولّد الأرقام العشوائية الزائفة.
التأثير
إذا تم استخدام مولّد أرقام عشوائية زائفة غير آمن بطريقة مشفَّرة في سياق أمان مثل المصادقة، قد يتمكّن المهاجم من تخمين الأرقام التي تم إنشاؤها عشوائيًا والوصول إلى بيانات أو ميزات مميّزة.
الإجراءات المخفّفة
بنود عامة
- استخدِم
java.security.SecureRandomعندما تكون هناك آثار أمنية - استخدِم
java.util.Randomفي أي حالات أخرى - لا تستخدِم
Math.randomأبدًا.
java.security.SecureRandom
يُنصح باستخدامه لأغراض الأمان. على Android، يعادل SecureRandom.getInstanceStrong() الحصول على SHA1PRNG من AndroidOpenSSL. ولا يرتبط بتنفيذ حظر /dev/random. لاستخدامه، عليك استدعاء getInstanceStrong():
Kotlin
val rand = SecureRandom.getInstanceStrong()
Java
SecureRandom rand = SecureRandom.getInstanceStrong();
بخلاف ذلك، في إصدارات Linux kernel السابقة للإصدار 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، ويتم استخدامه تلقائيًا عند إنشاء الكائن أو الحصول عليه، لذا ما مِن حاجة إلى تحديد القيمة العشوائية لمولّد الأرقام العشوائية الزائفة بشكلٍ صريح. بشكلٍ عام، لا يُنصح بأي استخدام حتمي لـ 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 لمولّد الأرقام العشوائية الزائفة الضعيف بطريقة مشفَّرة
- Java Secure Random
- Java Random مقابل SecureRandom
- كيفية استخدام SecureRandom
- إرشادات أمان مولّد الأرقام العشوائية الزائفة في Python
- ورقة الملاحظات الموجزة حول التخزين المشفَّر من OWASP
- CVE-2013-6386: ثغرة أمنية في مولّد الأرقام العشوائية الزائفة الضعيف في Drupal
- CVE-2006-3419: ثغرة أمنية في مولّد الأرقام العشوائية الزائفة الضعيف في Tor
- CVE-2008-4102: القيمة العشوائية التي يمكن توقّعها في Joomla
- تصحيح عشوائي في Linux Kernel