密码生成与校验工具
生成强密码与口令短语,支持批量、唯一性、强度与策略校验,并提供多语言代码示例与实用知识。
密码哈希速查表
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)
- 可配置字符集与符号分组
- 相似字符过滤与自定义排除
- 批量生成、唯一性保障与去重统计
- 强度与熵指标
- 策略测试器与口令短语生成器
- 多语言代码示例 (JS、Python、PHP、Go、Java、C#、Rust)
- 一键复制(单条/全部)
密码知识库
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');
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);
}