فئة OWASP: MASVS-CRYPTO: التشفير
نظرة عامة
مُنشئ الأرقام العشوائية الزائفة (PRNG) هو خوارزمية تنشئ تسلسلات أرقام يمكن توقّعها استنادًا إلى قيمة بداية تُعرف باسم القيمة العشوائية. ويحتوي تسلسل الأرقام الذي ينشئه مُنشئ الأرقام العشوائية الزائفة على الخصائص نفسها تقريبًا التي يحتوي عليها تسلسل الأرقام العشوائية الحقيقية، ولكن إنشاءه أسرع وأقل تكلفة من الناحية الحسابية.
بعبارة أخرى، يقدّم مُنشئو الأرقام العشوائية الزائفة ضمانات أعلى من مُنشئي الأرقام العشوائية الضعيفة (مثل java.math.Random) من حيث التوزيع المتساوي للإنتروبيا، ما يحاكي تسلسلات الأرقام العشوائية الحقيقية. ويتطلّب إنشاء أرقام عشوائية حقيقية معدّات متخصّصة، وغالبًا ما يكون خارج نطاق التطوير العادي. لا يتناول هذا المستند إنشاء أرقام عشوائية حقيقية، ويركّز فقط على مُنشئي الأرقام العشوائية الزائفة لأنّهم المنهجية العادية المستخدَمة.
تحدث الثغرات الأمنية في مُنشئي الأرقام العشوائية الزائفة الضعيفة عندما يستخدم المطوّرون مُنشئ أرقام عشوائية زائفة عاديًا لأغراض التشفير، بدلاً من مُنشئ أرقام عشوائية زائفة آمن بطريقة مشفّرة (CSPRNG). يفرض مُنشئو الأرقام العشوائية الزائفة الآمنة بطريقة مشفّرة متطلبات أكثر صرامة، وعندما تكون القيمة العشوائية غير معروفة، يجب ألا يمنحوا المهاجم سوى ميزة ضئيلة في التمييز بين تسلسل الإخراج وتسلسل عشوائي فعلي.
قد يتمكّن المهاجمون أيضًا من تخمين تسلسل الأرقام الذي تم إنشاؤه عند استخدام قيم عشوائية يمكن توقّعها، مثل تلك التي تم ترميزها بشكل ثابت من قِبل المطوّر، لتهيئة مُنشئ أرقام عشوائية زائفة أو مُنشئ أرقام عشوائية زائفة آمن بطريقة مشفّرة، لأنّ المهاجم يمكنه تخمين القيمة العشوائية وبالتالي توقّع الإخراج الذي ينشئه مُنشئ الأرقام العشوائية الزائفة.
التأثير
إذا تم استخدام مُنشئ أرقام عشوائية زائفة غير آمن بطريقة مشفّرة في سياق أمان مثل المصادقة، قد يتمكّن المهاجم من تخمين الأرقام التي تم إنشاؤها عشوائيًا والوصول إلى بيانات أو ميزات مميّزة.
الإجراءات المخفّفة
بنود عامة
- استخدِم
java.security.SecureRandomعندما تكون هناك آثار أمنية - استخدِم
java.util.Randomفي أي حالات أخرى - لا تستخدِم
Math.randomأبدًا.
java.security.SecureRandom
يُنصح باستخدامه لأغراض الأمان. إذا كان إصدار Linux kernel هو 5.17 أو إصدار أحدث أو كان حظر سلسلة المحادثات مقبولاً، انتظِر إلى أن تتراكم إنتروبيا كافية قبل إنشاء الأرقام العشوائية (أي استخدِم /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