All Tools / Blog / JavaScript और Python में सुरक्षित रैंडम पासवर्ड कैसे बनाएं

JavaScript और Python में सुरक्षित रैंडम पासवर्ड कैसे बनाएं

4 min read

ज़्यादातर लोग Math.random() से पासवर्ड जेनरेटर बनाते हैं — जो वास्तव में सुरक्षित नहीं होता। ब्रूट-फ़ोर्स अटैक से बचने वाला पासवर्ड बनाने के लिए क्रिप्टोग्राफिक रूप से सुरक्षित रैंडम नंबर जेनरेटर चाहिए। यह गाइड सही तरीका दिखाता है।

पासवर्ड को क्या सुरक्षित बनाता है?

पासवर्ड की मज़बूती दो बातों पर निर्भर है: लंबाई और कैरेक्टर सेट का आकार। एंट्रॉपी (बिट्स में) दोनों को मापती है:

entropy = log2(character_set_size ^ length)
         = length × log2(character_set_size)

व्यावहारिक लक्ष्य:

  • 128 बिट्स — ज़्यादातर उपयोग के लिए सुरक्षित
  • 80 बिट्स — किसी भी ज़रूरी चीज़ के लिए न्यूनतम
  • < 40 बिट्स — कंज़्यूमर हार्डवेयर से क्रैक हो सकता है
पासवर्ड टाइप प्रति कैरेक्टर बिट्स 128-बिट एंट्रॉपी के लिए लंबाई
केवल लोअरकेस (26 कैरेक्टर) 4.7 28 कैरेक्टर
मिक्स केस + अंक (62 कैरेक्टर) 5.95 22 कैरेक्टर
पूरी प्रिंटेबल ASCII (94 कैरेक्टर) 6.55 20 कैरेक्टर
Diceware शब्द (7,776 शब्द) 12.9 10 शब्द

अपरकेस, लोअरकेस, अंक और सिंबल वाला 20-कैरेक्टर पासवर्ड ~128 बिट्स एंट्रॉपी देता है।

JavaScript — ब्राउज़र

crypto.getRandomValues() उपयोग करें — यही एकमात्र सही API है। Math.random() कभी इस्तेमाल न करें।

function generatePassword(length = 20, options = {}) {
    const {
        uppercase = true,
        lowercase = true,
        digits = true,
        symbols = true,
    } = options;

    let chars = '';
    if (uppercase) chars += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    if (lowercase) chars += 'abcdefghijklmnopqrstuvwxyz';
    if (digits)    chars += '0123456789';
    if (symbols)   chars += '!@#$%^&*()-_=+[]{}|;:,.<>?';

    if (!chars) throw new Error('कम से कम एक कैरेक्टर सेट सक्षम होना चाहिए');

    const array = new Uint32Array(length);
    crypto.getRandomValues(array);

    return Array.from(array, x => chars[x % chars.length]).join('');
}

console.log(generatePassword(20));
// "kT9!mP2#xQ7@rL5$nW8^"

अगर आपको परफ़ेक्ट यूनिफ़ॉर्मिटी चाहिए (जैसे क्रिप्टोग्राफिक की मटेरियल के लिए), रिजेक्शन सैंपलिंग उपयोग करें:

function secureSample(chars, length) {
    const result = [];
    while (result.length < length) {
        const bytes = new Uint8Array(length * 2);
        crypto.getRandomValues(bytes);
        for (const b of bytes) {
            if (result.length >= length) break;
            if (b < Math.floor(256 / chars.length) * chars.length) {
                result.push(chars[b % chars.length]);
            }
        }
    }
    return result.join('');
}

JavaScript — Node.js

const crypto = require('crypto');

function generatePassword(length = 20) {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()';
    const bytes = crypto.randomBytes(length);
    return Array.from(bytes, b => chars[b % chars.length]).join('');
}

console.log(generatePassword(24));
// "Xm9kQ!rL2nP@jT5vW8sZ#hK"

Python

Python का secrets मॉड्यूल (Python 3.6+) सही टूल है — यह OS के क्रिप्टोग्राफिक सुरक्षित RNG का उपयोग करता है।

import secrets
import string

def generate_password(length: int = 20) -> str:
    alphabet = string.ascii_letters + string.digits + string.punctuation
    return ''.join(secrets.choice(alphabet) for _ in range(length))

print(generate_password(20))
# "k!T9mP2#xQ7@rL5$nW8^"

secrets.choice() OS CSPRNG से चुनता है। random.choice() उपयोग न करें — random मॉड्यूल क्रिप्टोग्राफिक रूप से सुरक्षित नहीं है।

कस्टम कैरेक्टर सेट:

import secrets
import string

def generate_password(
    length: int = 20,
    uppercase: bool = True,
    lowercase: bool = True,
    digits: bool = True,
    symbols: bool = True,
) -> str:
    chars = ''
    required = []

    if uppercase:
        chars += string.ascii_uppercase
        required.append(secrets.choice(string.ascii_uppercase))
    if lowercase:
        chars += string.ascii_lowercase
        required.append(secrets.choice(string.ascii_lowercase))
    if digits:
        chars += string.digits
        required.append(secrets.choice(string.digits))
    if symbols:
        sym = '!@#$%^&*()-_=+[]{}|;:,.<>?'
        chars += sym
        required.append(secrets.choice(sym))

    if not chars:
        raise ValueError('कम से कम एक कैरेक्टर सेट सक्षम होना चाहिए')

    remaining = length - len(required)
    pool = required + [secrets.choice(chars) for _ in range(remaining)]

    secrets.SystemRandom().shuffle(pool)
    return ''.join(pool)

print(generate_password(24))

यह हर सक्षम सेट से कम से कम एक कैरेक्टर सुनिश्चित करता है, फिर शफ़ल करता है — पहला कैरेक्टर अनुमानित नहीं होता।

कमांड लाइन

macOS/Linux — openssl:

# 20-कैरेक्टर base64 पासवर्ड
openssl rand -base64 20

# 20-कैरेक्टर hex पासवर्ड
openssl rand -hex 20

# केवल अल्फ़ान्यूमेरिक
openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 20

Linux — /dev/urandom:

# प्रिंटेबल ASCII कैरेक्टर
cat /dev/urandom | tr -dc 'a-zA-Z0-9!@#$%^&*' | head -c 20; echo

Python one-liner:

python3 -c "import secrets, string; print(''.join(secrets.choice(string.ascii_letters + string.digits + '!@#$%^&*') for _ in range(20)))"

पासफ़्रेज़ (Diceware)

4–6 रैंडम शब्दों की पासफ़्रेज़ एक छोटे रैंडम पासवर्ड से ज़्यादा सुरक्षित हो सकती है — और याद रखना भी आसान।

import secrets

# EFF बड़ी वर्डलिस्ट में 7776 शब्द हैं (6 पासे की रोल)
# डाउनलोड: https://www.eff.org/files/2016/07/18/eff_large_wordlist.txt

def generate_passphrase(word_count: int = 5, wordlist_path: str = 'eff_large_wordlist.txt') -> str:
    with open(wordlist_path) as f:
        words = [line.split('\t')[1].strip() for line in f if '\t' in line]
    return '-'.join(secrets.choice(words) for _ in range(word_count))

print(generate_passphrase(5))
# "crumpet-waffle-harbor-slime-donkey"

EFF वर्डलिस्ट से 5 शब्द ~64.6 बिट्स एंट्रॉपी देते हैं। 6 शब्द ~77.5 बिट्स।

क्या उपयोग न करें

  • Math.random() (JavaScript) — PRNG उपयोग करता है, CSPRNG नहीं।
  • random.random() / random.choice() (Python) — यही समस्या।
  • कोई भी सिस्टम जो timestamp या username हैश करता है।
  • 12 कैरेक्टर से कम पासवर्ड।

मुख्य बातें

  • ब्राउज़र JavaScript में crypto.getRandomValues(), Node.js में crypto.randomBytes() उपयोग करें।
  • Python में secrets.choice()random.choice() नहीं।
  • कमांड लाइन से openssl rand उपयोग करें।
  • ~128 बिट्स एंट्रॉपी के लिए मिक्स कैरेक्टर सेट के साथ 20+ कैरेक्टर लक्ष्य रखें।
  • Diceware पासफ़्रेज़ एक बढ़िया विकल्प है — लंबी और अधिक यादगार।