দুর্বল PRNG

OWASP বিভাগ: MASVS-CRYPTO: ক্রিপ্টোগ্রাফি

সংক্ষিপ্ত বিবরণ

সিউডোর‍্যান্ডম নাম্বার জেনারেটর (PRNG) হলো এমন একটি অ্যালগরিদম যা ' সিড' নামক একটি প্রারম্ভিক মানের উপর ভিত্তি করে পূর্বাভাসযোগ্য সংখ্যা অনুক্রম তৈরি করে। PRNG দ্বারা তৈরি একটি সংখ্যা অনুক্রমের বৈশিষ্ট্যগুলো প্রায় একটি সত্যিকারের র‍্যান্ডম সংখ্যা অনুক্রমের মতোই, কিন্তু এটি তৈরি করা দ্রুততর এবং এতে গণনার খরচও কম।

অন্য কথায়, এনট্রপি বণ্টনের সমতার দিক থেকে PRNG-গুলো দুর্বল RNG-এর (যেমন java.math.Random ) চেয়ে উচ্চতর নিশ্চয়তা প্রদান করে, যা প্রকৃত র‍্যান্ডম সংখ্যার অনুক্রমকে অনুকরণ করে। প্রকৃত র‍্যান্ডম সংখ্যা তৈরির জন্য বিশেষায়িত সরঞ্জামের প্রয়োজন হয় এবং এটি প্রায়শই সাধারণ উন্নয়নের আওতার বাইরে থাকে। এই নথিতে প্রকৃত র‍্যান্ডম সংখ্যা তৈরির বিষয়টি আলোচনা করা হয়নি এবং শুধুমাত্র PRNG-এর উপর আলোকপাত করা হয়েছে, কারণ এটিই বর্তমানে ব্যবহৃত আদর্শ পদ্ধতি।

দুর্বল PRNG দুর্বলতা তখন দেখা দেয়, যখন ডেভেলপাররা ক্রিপ্টোগ্রাফিক উদ্দেশ্যে ক্রিপ্টোগ্রাফিকভাবে-সুরক্ষিত PRNG (CSPRNG)-এর পরিবর্তে একটি সাধারণ PRNG ব্যবহার করেন। CSPRNG-এর জন্য আরও কঠোর শর্তাবলী রয়েছে, এবং যখন সিড (seed) অজানা থাকে, তখন একটি আউটপুট সিকোয়েন্সকে প্রকৃত র‍্যান্ডম সিকোয়েন্স থেকে আলাদা করার ক্ষেত্রে এটি আক্রমণকারীকে শুধুমাত্র একটি নগণ্য সুবিধা দিতে পারে।

যখন কোনো PRNG বা CSPRNG শুরু করার জন্য অনুমানযোগ্য সিড—যেমন ডেভেলপার কর্তৃক হার্ড কোড করা সিড—ব্যবহার করা হয়, তখন আক্রমণকারীরা উৎপন্ন সংখ্যা ক্রমটিও অনুমান করতে সক্ষম হতে পারে, কারণ আক্রমণকারী সিডটি অনুমান করে PRNG দ্বারা উৎপন্ন আউটপুট আগে থেকে অনুমান করতে পারে।

প্রভাব

যদি প্রমাণীকরণের মতো কোনো নিরাপত্তা প্রসঙ্গে ক্রিপ্টোগ্রাফিকভাবে অসুরক্ষিত PRNG ব্যবহার করা হয়, তাহলে একজন আক্রমণকারী এলোমেলোভাবে তৈরি সংখ্যাগুলো অনুমান করে বিশেষাধিকারপ্রাপ্ত ডেটা বা বৈশিষ্ট্যগুলিতে অ্যাক্সেস পেতে সক্ষম হতে পারে।

প্রশমন

সাধারণ

  • নিরাপত্তাজনিত ঝুঁকি থাকলে java.security.SecureRandom ব্যবহার করুন।
  • অন্যান্য ক্ষেত্রে java.util.Random ব্যবহার করুন।
  • কখনোই Math.random ব্যবহার করবেন না!

java.security.SecureRandom

নিরাপত্তাজনিত ব্যবহারের জন্য সুপারিশকৃত । যদি লিনাক্স কার্নেল সংস্করণ 5.17+ হয় অথবা থ্রেড ব্লক করা গ্রহণযোগ্য হয়, তাহলে র‍্যান্ডম সংখ্যা তৈরি করার আগে পর্যাপ্ত এনট্রপি জমা হওয়ার জন্য অপেক্ষা করুন (অর্থাৎ /dev/random ব্যবহার করুন)। এটি করার জন্য, getInstanceStrong() কল করুন:

কোটলিন

val rand = SecureRandom.getInstanceStrong()

জাভা

SecureRandom rand = SecureRandom.getInstanceStrong();

অন্যথায়, লিনাক্স কার্নেলের 5.17-এর পূর্ববর্তী সংস্করণগুলিতে র‍্যান্ডম সংখ্যা তৈরি করার সময় থ্রেড ব্লক করা অগ্রহণযোগ্য হলে, সরাসরি SecureRandom কনস্ট্রাক্টরকে কল করা উচিত:

কোটলিন

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

জাভা

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

নিরাপত্তা বা প্রমাণীকরণের উদ্দেশ্যে পরিহার করুন , অন্য যেকোনো ক্ষেত্রে ব্যবহার করা যেতে পারে।

কোটলিন

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

জাভা

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

সম্পদ