Trình Tạo Mật Khẩu
Tạo mật khẩu ngẫu nhiên mạnh mẽ có độ dài và bộ ký tự có thể tùy chỉnh
Trình Tạo Mật Khẩu là gì?
Trình tạo mật khẩu tạo ra các chuỗi ký tự ngẫu nhiên được dùng làm mật khẩu cho tài khoản người dùng, khóa API, thông tin xác thực cơ sở dữ liệu và bí mật mã hóa. Khác với mật khẩu do con người tự chọn, mật khẩu được tạo tự động lấy từ toàn bộ không gian tổ hợp ký tự có thể, khiến chúng có khả năng chống lại các cuộc tấn công từ điển và đoán theo mẫu. Công cụ này tạo mật khẩu ngẫu nhiên mạnh mẽ trực tuyến bằng bộ tạo số ngẫu nhiên mật mã tích hợp sẵn của trình duyệt.
Độ mạnh của mật khẩu phụ thuộc vào hai yếu tố: độ dài và sự đa dạng ký tự. Một mật khẩu 20 ký tự sử dụng chữ hoa, chữ thường, chữ số và ký hiệu có khoảng 131 bit entropy. Ở mức đó, một cuộc tấn công brute-force kiểm tra một nghìn tỷ lần đoán mỗi giây sẽ cần nhiều thời gian hơn tuổi của vũ trụ để thử mọi tổ hợp. Công thức rất đơn giản: entropy = độ dài x log2(kích thước bộ ký tự).
Các tiêu chuẩn như NIST SP 800-63B khuyến nghị mật khẩu có ít nhất 8 ký tự mà không có giới hạn trên do bên xác minh áp đặt, và không khuyến khích các quy tắc thành phần bắt buộc như yêu cầu chính xác một ký hiệu, thay vào đó ưu tiên cụm từ mật khẩu dài hơn. Đối với thông tin xác thực máy-máy và tài khoản dịch vụ, 20 ký tự ngẫu nhiên trở lên được lấy từ bộ ký tự đầy đủ là tiêu chuẩn được chấp nhận trong hầu hết các khung bảo mật và chế độ tuân thủ.
Tại sao Dùng Trình Tạo Mật Khẩu?
Con người là những bộ tạo số ngẫu nhiên kém. Chúng ta tái sử dụng mật khẩu, chọn các từ trong từ điển, thay thế chữ cái theo các mẫu có thể đoán trước (@ thay cho a, 3 thay cho e) và mặc định dùng chuỗi ngắn. Trình tạo mật khẩu loại bỏ sự thiên lệch của con người khỏi quy trình.
Các Trường Hợp Sử Dụng Trình Tạo Mật Khẩu
Bảng Tham Chiếu Entropy Mật Khẩu
Entropy đo mức độ khó đoán của mật khẩu. Được tính bằng log2(kích_thước_bộ_ký_tự ^ độ_dài). Entropy cao hơn có nghĩa là nhiều tổ hợp có thể hơn để kẻ tấn công phải dò qua. NIST và OWASP khuyến nghị ít nhất 80 bit entropy cho các ứng dụng bảo mật cao.
| Độ Dài | Bộ Ký Tự | Entropy | Thời Gian Brute-Force |
|---|---|---|---|
| 8 | lower + digits | ~41 bits | Minutes to hours |
| 12 | lower + upper + digits | ~71 bits | Centuries (offline) |
| 16 | all character sets | ~105 bits | Beyond brute-force |
| 20 | all character sets | ~131 bits | Beyond brute-force |
| 32 | all character sets | ~210 bits | Beyond brute-force |
| 64 | all character sets | ~419 bits | Beyond brute-force |
Thời gian dò mật khẩu giả định 1 nghìn tỷ lần đoán mỗi giây (tấn công offline với GPU hiện đại). Các cuộc tấn công trực tuyến có giới hạn tốc độ chậm hơn nhiều bậc độ lớn.
CSPRNG so với Math.random() để Tạo Mật Khẩu
Nguồn tạo số ngẫu nhiên quan trọng không kém độ dài mật khẩu. Mật khẩu được tạo bằng bộ tạo số ngẫu nhiên có thể đoán trước có thể bị kẻ tấn công tái tạo nếu họ biết thuật toán và trạng thái hạt giống. Công cụ này dùng crypto.getRandomValues(), là bộ tạo số giả ngẫu nhiên an toàn về mặt mật mã (CSPRNG) được tích hợp sẵn trong mọi trình duyệt hiện đại.
Ví Dụ Code
Tạo mật khẩu theo chương trình trong các ngôn ngữ khác nhau. Mọi ví dụ dưới đây đều dùng nguồn ngẫu nhiên an toàn về mặt mật mã, không phải Math.random() hoặc các PRNG yếu tương đương.
// Generate a random password in the browser or Node.js 19+
function generatePassword(length = 20) {
const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'
const values = new Uint32Array(length)
crypto.getRandomValues(values)
return Array.from(values, v => charset[v % charset.length]).join('')
}
console.log(generatePassword()) // → "kR7!mZp$Xw2&nLq9@Yf3"
console.log(generatePassword(32)) // → "Hd4%tNx!Qw8#mKp2Rv6&Zj0*Ls3Yb7@"import secrets
import string
def generate_password(length: int = 20) -> str:
"""Generate a cryptographically secure random password."""
alphabet = string.ascii_letters + string.digits + string.punctuation
return ''.join(secrets.choice(alphabet) for _ in range(length))
# Single password
print(generate_password()) # → "kR7!mZp$Xw2&nLq9@Yf3"
# Batch of 5 passwords
for _ in range(5):
print(generate_password(24))
# Ensure at least one char from each category
def generate_strong(length: int = 20) -> str:
required = [
secrets.choice(string.ascii_uppercase),
secrets.choice(string.ascii_lowercase),
secrets.choice(string.digits),
secrets.choice(string.punctuation),
]
remaining = length - len(required)
alphabet = string.ascii_letters + string.digits + string.punctuation
all_chars = required + [secrets.choice(alphabet) for _ in range(remaining)]
secrets.SystemRandom().shuffle(all_chars)
return ''.join(all_chars)# OpenSSL — generate 32 random bytes, base64-encode openssl rand -base64 32 # → "x7Kp2mNqR4wZ8vLs1Yb0Hd6tFj3Xc9Ga5eUi+Wo=" # /dev/urandom with tr — alphanumeric + symbols, 20 chars tr -dc 'A-Za-z0-9!@#$%^&*' < /dev/urandom | head -c 20; echo # → "kR7!mZp$Xw2&nLq9@Yf3" # pwgen (install: apt install pwgen / brew install pwgen) pwgen -sy 20 5 # Generates 5 passwords, 20 chars each, with symbols
package main
import (
"crypto/rand"
"fmt"
"math/big"
)
func generatePassword(length int) (string, error) {
charset := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"
result := make([]byte, length)
for i := range result {
idx, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
if err != nil {
return "", err
}
result[i] = charset[idx.Int64()]
}
return string(result), nil
}
func main() {
pwd, _ := generatePassword(20)
fmt.Println(pwd) // → "kR7!mZp$Xw2&nLq9@Yf3"
}