कमज़ोर पीआरएनजी

OWASP कैटगरी: MASVS-CRYPTO: क्रिप्टोग्राफ़ी

खास जानकारी

स्यूडोरैंडम नंबर जनरेटर (पीआरएनजी) एक ऐसा एल्गोरिदम है जो अनुमानित संख्या वाले क्रम जनरेट करता है. यह क्रम, सीड नाम की शुरुआती वैल्यू पर आधारित होता है. PRNG से जनरेट किए गए नंबर के क्रम में, लगभग वही प्रॉपर्टी होती हैं जो रैंडम नंबर के क्रम में होती हैं. हालांकि, इसे जनरेट करने में कम समय लगता है और यह कम कंप्यूटेशनल होता है.

दूसरे शब्दों में कहें, तो एंट्रॉपी डिस्ट्रिब्यूशन की एकरूपता के मामले में, पीआरएनजी में कमज़ोर आरएनजी (जैसे, java.math.Random) की तुलना में ज़्यादा भरोसा होता है. ये पूरी तरह से रैंडम नंबर सीक्वेंस की नकल करते हैं. सही मायने में रैंडम नंबर जनरेट करने के लिए, खास तरह के उपकरण की ज़रूरत होती है. साथ ही, यह अक्सर सामान्य डेवलपमेंट के दायरे से बाहर होता है. इस दस्तावेज़ में, पूरी तरह से रैंडम नंबर जनरेट करने के बारे में नहीं बताया गया है. इसमें सिर्फ़ पीआरएनजी पर फ़ोकस किया गया है, क्योंकि यह इस्तेमाल की जाने वाली स्टैंडर्ड तरीके है.

कमज़ोर पीआरएनजी की कमियां तब होती हैं, जब डेवलपर क्रिप्टोग्राफ़िक मकसद के लिए, क्रिप्टोग्राफ़िक तौर पर सुरक्षित पीआरएनजी (सीएसपीआरएनजी) के बजाय, सामान्य पीआरएनजी का इस्तेमाल करते हैं. CSPRNG के लिए, ज़्यादा ज़रूरी शर्तें होती हैं. साथ ही, जब सीड के बारे में जानकारी नहीं होती है, तब हमलावर को आउटपुट सीक्वेंस को असली रैंडम सीक्वेंस से अलग करने में सिर्फ़ मामूली फ़ायदा मिलना चाहिए.

हमलावर, जनरेट की गई संख्या के क्रम का अनुमान भी लगा सकते हैं. ऐसा तब होता है, जब पीआरएनजी या सीएसपीआरएनजी को शुरू करने के लिए अनुमान लगाने लायक सीड का इस्तेमाल किया जाता है. जैसे, डेवलपर की ओर से हार्ड कोड किए गए सीड. ऐसा इसलिए होता है, क्योंकि हमलावर सीड का अनुमान लगा सकता है. इस वजह से, वह पीआरएनजी से जनरेट किए गए आउटपुट का अनुमान लगा सकता है.

असर

अगर क्रिप्टोग्राफ़िक रूप से सुरक्षित न होने वाले पीआरएनजी का इस्तेमाल सुरक्षा से जुड़े किसी संदर्भ में किया जाता है, जैसे कि पुष्टि करना, तो हमलावर रैंडम तरीके से जनरेट किए गए नंबरों का अनुमान लगा सकता है. साथ ही, वह खास डेटा या सुविधाओं को ऐक्सेस कर सकता है.

जोखिम कम करने के तरीके

सामान्य

  • सुरक्षा से जुड़ी समस्याएं होने पर, 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 कंस्ट्रक्टर को सीधे तौर पर कॉल किया जाना चाहिए:

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 का इस्तेमाल करने से बचने का सुझाव दिया जाता है. खास तौर पर, तब जब इससे सीड वैल्यू को हार्ड कोड किया जाता है. इसे ऐप्लिकेशन को डीकंपाइल करने वाला कोई भी व्यक्ति देख सकता है. जिन डेवलपर को दोबारा बनाए जा सकने वाले स्यूडोरैंडम आउटपुट जनरेट करने हैं उन्हें एचएमएसी, एचकेडीएफ़, और शेक जैसे ज़्यादा सही प्रिमिटिव का इस्तेमाल करना चाहिए.

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);
    }
}

संसाधन