密碼生成與校驗工具
專業密碼生成與校驗工具,支持生成強密碼與易記口令短語,提供批量生成、唯一性保障、強度評估與策略校驗功能。內建安全隨機源、可配置字元集、相似字元過濾、批量去重統計等特性,提供多語言程式碼範例、密碼知識庫和安全實踐指南,所有操作均在本地完成,確保隱私安全。
密碼雜湊速查表
Argon2id
- 使用 Argon2id,並設置合理的記憶硬參數
- 時間 ≥ 2 次遍歷,記憶 ≥ 64MB(按環境調校)
- 每使用者儲存獨立鹽;可選在應用層使用 pepper
PBKDF2
- 選擇 SHA-256 或 SHA-512,迭代 ≥ 210k(按需調校)
- 每個雜湊使用唯一鹽;支援參數升級
- 使用者下次登入時遷移到更高成本參數
BCrypt
- 成本 10–14,取決於伺服器能力
- 避免截斷問題;應對完整密碼進行雜湊
- 對認證端點做限流與監控
參考:NIST SP 800-63B、OWASP ASVS。參數需與硬體能力與 SLO 匹配。
密碼強度評估
強度近似來源於熵:entropy = log2(字元池大小) × 長度。更大的字元池與更長的長度可提升抗猜測能力。
- 弱: < 50 bits —— 僅適合一次性/低價值場景
- 一般: 50–80 bits —— 可接受於低風險場景
- 強: 80–110 bits —— 推薦的預設目標
- 極強: > 110 bits —— 適用於管理員/關鍵帳戶
提示:真實攻擊模型會有差異;請避免密碼重複並開啟多因素認證(MFA)。
使用說明
- 選擇長度與字元集(Lower/Upper/Digits/Symbols);必要時開啟 Avoid similar、Require each
- 需要更細控制時:排除字元/字元組,或選擇符號分組
- 選擇生成數量,點擊生成;批次結果自動去重,可一鍵複製全部
- 想校驗現有密碼,用「策略測試器」;想易記口令,用「口令短語生成器」
功能特性
- 安全隨機源(Web Crypto)
- 可配置字元集與符號分組
- 相似字元過濾與自定義排除
- 批量生成 1–100 個,自動保證唯一
- 強度與熵指標
- 策略測試器與口令短語生成器
- 多語言程式碼範例
- 一鍵複製(單條/全部)
密碼知識庫
1) 密碼強度與熵
- 熵 ≈ log2(字元池大小) × 長度;長度貢獻通常更大
- 建議目標:普通帳號 ≥ 80 bits;高權限/財務 ≥ 110 bits
- 更大字元池+更長長度 → 更抗猜測
2) 長度 vs 複雜度
- 盲目堆疊符號不如增加長度有效
- 避免固定可預測模式(如每次都「首字母大寫+結尾數字!」)
- 優先確保足夠長度,再適度提升字元多樣性
3) 常見誤區與反模式
- 鍵盤序列(qwerty)、重複區塊、生日/年份等易被規則命中
- 「根密碼+網站後綴」是變體復用,風險集中且易被猜出
- 不要在多個網站重複使用同一密碼
4) 密碼管理建議
- 使用密碼管理器;每站唯一;重要帳戶開啟 MFA
- 避免在公共渠道明文傳遞;必要時使用「發音友好型」口令
- 發現洩露或復用,立即更換並做到唯一化
5) 口令短語(Passphrase)指南
- 多詞組合(4–6 詞)通常強且易記
- 混合分隔符、首字母大寫、插入數字可提升強度與可讀
- 避免常見短語/歌詞/名言的直接拼接
密碼安全實踐指南
最佳實踐
- 盡量使用足夠長度:一般帳戶 16+,關鍵帳戶 24+
- 記憶需求可優先使用口令短語;隨機高強度密碼建議交由密碼管理器保存
- 盡可能開啟多因素認證(MFA)
- 不同網站不要復用密碼,每個帳戶都應唯一
熵與強度
熵反映基於長度與字元池大小的不可預測性,熵位數越高通常越強。
- 優先增加長度獲得最大收益
- 在可行情況下使用多種字元集
- 過度排除字元會縮小字元池、降低強度
策略與輪換
- 比起複雜的組成規則,更偏向長度與禁用常見/洩露密碼的黑名單
- 避免頻繁強制輪換;在出現洩露或風險時再更改
- 使用洩露密碼名單阻止常見/洩露密碼
口令短語
- 使用 4–6 個隨機詞並用分隔符連接,例如 lake-CARROT-planet_7
- 避免引用名句/歌詞等常見短語;隨機性比「機智」更重要
- 關鍵帳戶建議使用密碼管理工具保存真正高熵的隨機密碼
生成設定提示
- 「Require each selected set」可確保每類至少出現一次
- 「Avoid similar」提升可讀性,但會略微降低字元池大小
- 符號可限制為目標系統可接受的子集
伺服器端儲存
- 切勿明文儲存;使用強雜湊(Argon2id/PBKDF2/BCrypt)並配鹽
- 合理設定參數(記憶體/時間/成本),需要時使用 pepper
- 限制速率並監控失敗嘗試;遭受攻擊時加驗證碼或裝置驗證
多因素與找回
- 優先使用 TOTP/硬體金鑰;盡量避免 SMS
- 保護找回流程:多因子或電子郵件驗證並設定冷卻期
- 提供備用回復碼並建議使用者妥善保管
暴力破解防護
- 使用漸進式延遲/鎖定與 IP/裝置風險評分
- 為 API 與登入表單設定 WAF/限流
- 監測撞庫並鼓勵使用者使用唯一密碼
本機儲存與處理
- 使用可靠的密碼管理工具進行儲存與自動填寫
- 不要透過聊天/郵件明文分享密碼;團隊使用機密管理工具
- 如需線下記錄,請確保實體安全
聲明:本工具在瀏覽器本機使用 Web Crypto 生成密碼;不會將資料傳送到伺服器。
如何通過程式語言產生密碼
JavaScript (Web Crypto)
function randomPassword(length = 16, sets = {lower:true, upper:true, digits:true, symbols:true}) {
const pools = {
lower: 'abcdefghijklmnopqrstuvwxyz',
upper: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
digits: '0123456789',
symbols: '!@#$%^&*+-=_~`|/?()[]{}<>,.;:\'\"'
};
let pool = '';
for (const k of Object.keys(sets)) if (sets[k]) pool += pools[k];
if (!pool) throw new Error('No charset');
// Rejection sampling removes modulo bias
const limit = Math.floor(0x100000000 / pool.length) * pool.length;
const buf = new Uint32Array(1);
let out = '';
for (let i = 0; i < length; i++) {
do { crypto.getRandomValues(buf); } while (buf[0] >= limit);
out += pool[buf[0] % pool.length];
}
return out;
}
Python (secrets)
import secrets
def random_password(length=16, lower=True, upper=True, digits=True, symbols=True):
pools = {
'lower': 'abcdefghijklmnopqrstuvwxyz',
'upper': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'digits': '0123456789',
'symbols': '!@#$%^&*+-=_~`|/?()[]{}<>,.;:\'\"'
}
pool = ''.join(v for k, v in pools.items() if locals()[k])
if not pool:
raise ValueError('No charset')
return ''.join(secrets.choice(pool) for _ in range(length))
PHP (random_int)
function random_password($length = 16, $sets = ['lower'=>true,'upper'=>true,'digits'=>true,'symbols'=>true]) {
$pools = [
'lower' => 'abcdefghijklmnopqrstuvwxyz',
'upper' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'digits' => '0123456789',
'symbols' => '!@#$%^&*+-=_~`|/?()[]{}<>,.;:\'\"'
];
$pool = '';
foreach ($sets as $k => $on) if ($on) $pool .= $pools[$k];
if ($pool === '') throw new Exception('No charset');
$out = '';
for ($i = 0; $i < $length; $i++) {
$out .= $pool[random_int(0, strlen($pool)-1)];
}
return $out;
}
Go (crypto/rand)
package main
import (
"crypto/rand"
"math/big"
)
func RandomPassword(length int, pool string) (string, error) {
out := make([]byte, length)
for i := 0; i < length; i++ {
nBig, err := rand.Int(rand.Reader, big.NewInt(int64(len(pool))))
if err != nil { return "", err }
out[i] = pool[nBig.Int64()]
}
return string(out), nil
}
Java (SecureRandom)
import java.security.SecureRandom;
public class Pw {
static final String POOL = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*+-=_~`|/?()[]{}<>,.;:'\"";
static final SecureRandom SR = new SecureRandom();
static String randomPassword(int length) {
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
int idx = SR.nextInt(POOL.length());
sb.append(POOL.charAt(idx));
}
return sb.toString();
}
}
C# (.NET RandomNumberGenerator)
using System;
using System.Security.Cryptography;
public static class Pw {
public static string RandomPassword(int length, string pool) {
// GetInt32 draws an unbiased value in [0, pool.Length)
var chars = new char[length];
for (int i = 0; i < length; i++) {
chars[i] = pool[RandomNumberGenerator.GetInt32(pool.Length)];
}
return new string(chars);
}
}
Rust (rand + getrandom)
use rand::rngs::OsRng;
use rand::Rng;
fn random_password(length: usize, pool: &str) -> String {
// gen_range is uniform, so there is no modulo bias
let chars: Vec = pool.chars().collect();
(0..length)
.map(|_| chars[OsRng.gen_range(0..chars.len())])
.collect()
}
fn main() {
let pool = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*+-=_~`|/?()[]{}<>,.;:'\"";
let pw = random_password(16, pool);
println!("{}", pw);
}