Cara Membuat Password Acak yang Aman di JavaScript dan Python
Kebanyakan generator password yang orang buat sendiri menggunakan Math.random() — dan itu tidak aman. Untuk password yang tahan serangan brute-force, kamu perlu generator angka acak yang aman secara kriptografi. Panduan ini menunjukkan cara yang benar.
Apa yang membuat password aman?
Dua faktor menentukan kekuatan password: panjang dan ukuran set karakter. Entropi (dalam bit) mengukur keduanya:
entropi = log2(ukuran_set_karakter ^ panjang)
= panjang × log2(ukuran_set_karakter)
Target praktis:
- 128 bit — aman untuk sebagian besar kegunaan
- 80 bit — minimum untuk hal penting
- < 40 bit — bisa dipecahkan dengan hardware konsumer
| Jenis password | Bit per karakter | Panjang untuk 128-bit entropi |
|---|---|---|
| Huruf kecil saja (26 karakter) | 4,7 | 28 karakter |
| Campuran huruf + angka (62 karakter) | 5,95 | 22 karakter |
| ASCII cetak penuh (94 karakter) | 6,55 | 20 karakter |
| Kata Diceware (7.776 kata) | 12,9 | 10 kata |
Password 20 karakter dengan huruf besar, kecil, angka, dan simbol memiliki ~128 bit entropi. Itu targetnya.
JavaScript — browser
Gunakan crypto.getRandomValues() — satu-satunya API yang benar untuk ini. Jangan pernah gunakan 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('Minimal satu set karakter harus diaktifkan');
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^"
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
Modul secrets Python (Python 3.6+) adalah alat yang tepat — menggunakan CSPRNG dari sistem operasi.
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() memilih dari urutan menggunakan CSPRNG sistem operasi. Ini fungsi yang benar. Jangan gunakan random.choice() — modul random tidak aman secara kriptografi.
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('Minimal satu set karakter harus diaktifkan')
remaining = length - len(required)
pool = required + [secrets.choice(chars) for _ in range(remaining)]
secrets.SystemRandom().shuffle(pool)
return ''.join(pool)
print(generate_password(24))
Ini menjamin minimal satu karakter dari setiap set yang diaktifkan, lalu mengacak posisinya.
Command line
# macOS/Linux — openssl
openssl rand -base64 20
# Hanya alfanumerik
openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 20
# Linux — /dev/urandom
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)))"
Yang TIDAK boleh digunakan
Math.random()(JavaScript) — menggunakan PRNG, bukan CSPRNG. Bisa diprediksi.random.random()/random.choice()(Python) — masalah yang sama.- Sistem yang meng-hash timestamp atau username — tidak acak.
- Password di bawah 12 karakter — terlalu pendek untuk hal sensitif.
Ringkasan
- Gunakan
crypto.getRandomValues()di browser JavaScript,crypto.randomBytes()di Node.js. - Gunakan
secrets.choice()di Python — bukanrandom.choice(). - Gunakan
openssl randdari command line. - Target 20+ karakter dengan set karakter campuran untuk ~128 bit entropi.
Math.random()tidak aman untuk password — jangan gunakan untuk keperluan kriptografi.