密碼生成與校驗工具

專業密碼生成與校驗工具,支持生成強密碼與易記口令短語,提供批量生成、唯一性保障、強度評估與策略校驗功能。內建安全隨機源、可配置字元集、相似字元過濾、批量去重統計等特性,提供多語言程式碼範例、密碼知識庫和安全實踐指南,所有操作均在本地完成,確保隱私安全。

密碼產生器

選擇符號分組
提示:可通過選擇分組或直接點擊字元進行排除。
結果

密碼策略測試器

結果
  • 長度
  • 小寫字母
  • 大寫字母
  • 數字
  • 符號
  • 連續序列
  • 重複
  • 黑名單
所有校驗均在你的瀏覽器本地完成。

口令短語產生器

單詞使用安全隨機(Web Crypto)從 1271 個無歧義詞中均勻抽取;6 個詞約 62 bit 熵,需要更高強度可調到 8 個詞。

密碼雜湊速查表

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 個,自動保證唯一
  • 強度與熵指標
  • 策略測試器與口令短語生成器
  • 多語言程式碼範例
  • 一鍵複製(單條/全部)

密碼生成範例

強壯(Strong)
長度 24,包含大小寫/數字/符號
易記(Memorable)
長度 16,包含大小寫/數字,避免相似字元

密碼知識庫

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