密碼生成與驗證工具

產生強密碼與口令短語,支援批次生成、唯一性、強度與策略驗證,並提供多語言程式碼範例與實用知識。

密碼產生器

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

密碼策略測試器

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

口令短語產生器

單詞使用安全隨機(Web Crypto)選擇。示範詞表因體積限制而較短。

密碼雜湊速查表

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)。

使用說明

  • 選擇長度與字元集(小寫/大寫/數字/符號);必要時啟用「避免相似字元」與「必須包含每類」
  • 需要更精細控制時:排除特定字元或字元組,或選取符號分組
  • 點擊生成;如需多組結果,啟用批次生成並可一鍵複製全部
  • 想驗證現有密碼,請使用「策略測試器」;想建立易記口令,請使用「口令短語生成器」

功能特性

  • 安全隨機來源(Web Crypto)
  • 可設定字元集與符號分組
  • 相似字元過濾與自訂排除
  • 批次生成、唯一性保障與去重統計
  • 強度與熵值指標
  • 策略測試器與口令短語生成器
  • 多語言程式碼範例 (JS、Python、PHP、Go、Java、C#、Rust)
  • 一鍵複製(單條/全部)

密碼生成範例

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

密碼知識庫

1) 密碼強度與熵
  • 熵 ≈ log2(字元池大小) × 長度;長度的貢獻通常更大
  • 建議目標:一般帳號 ≥ 80 bits;高權限/財務帳戶 ≥ 110 bits
  • 更大的字元池 + 更長的長度 → 更能抵抗猜測
2) 長度 vs 複雜度
  • 盲目堆疊符號不如增加長度有效
  • 避免固定且可預測的模式(例如每次都「首字母大寫+結尾數字!」)
  • 優先確保足夠長度,再適度提升字元多樣性
3) 常見誤區與反模式
  • 鍵盤序列(如 qwerty)、重複區塊、生日/年份等易被規則命中
  • 「根密碼+網站後綴」是變體複用,風險集中且容易被猜出
  • 不要在多個網站重複使用同一密碼
4) 密碼管理建議
  • 使用密碼管理器;每個網站使用唯一密碼;重要帳戶啟用 MFA
  • 避免在公開管道明文傳遞密碼;必要時使用「發音友好型」口令
  • 發現洩露或重複使用時,立即更換並確保唯一性
5) 口令短語(Passphrase)指南
  • 四至六個詞的組合通常既強壯又易記
  • 混合分隔符、首字母大寫、插入數字可提升強度與可讀性
  • 避免直接拼接常見短語、歌詞或名言

密碼安全實踐指南

最佳實踐
  • 盡量使用足夠長度:一般帳戶 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');
  const bytes = new Uint32Array(length);
  crypto.getRandomValues(bytes);
  let out = '';
  for (let i = 0; i < length; i++) out += pool[bytes[i] % 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) {
    using var rng = RandomNumberGenerator.Create();
    var bytes = new byte[length];
    rng.GetBytes(bytes);
    var chars = new char[length];
    for (int i = 0; i < length; i++) {
      chars[i] = pool[bytes[i] % pool.Length];
    }
    return new string(chars);
  }
}
Rust(rand + getrandom)
use rand::rngs::OsRng;
use rand::RngCore;

fn random_password(length: usize, pool: &str) -> String {
    let mut bytes = vec![0u8; length];
    OsRng.fill_bytes(&mut bytes);
    let chars: Vec = pool.chars().collect();
    bytes
        .iter()
        .map(|b| chars[(*b as usize) % chars.len()])
        .collect()
}

fn main() {
    let pool = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*+-=_~`|/?()[]{}<>,.;:'\"";
    let pw = random_password(16, pool);
    println!("{}", pw);
}