密码安全完全指南:如何生成与管理真正可靠的强密码

安全指南

你的密码,可能比你想的更脆弱

几乎每个月都有大网站泄露用户数据的消息。泄露之后,最危险的不是「我的密码被看到了」,而是大多数人一套密码走天下——A 站泄露的账号密码,攻击者拿去撞 B 站、C 站,十有八九能直接登进去。

还有一类人走另一个极端:把 P@ssw0rd1! 当成「够复杂了」。这其实是自欺欺人。我们在做工具库的密码工具这几年反复强调一件事:密码的强度不是你「觉得」多复杂,而是它实际有多难被算出来

根据 Have I Been Pwned 等泄露库统计,常年出现在撞库字典里的弱密码就那么几百个变体。password123456qwertyP@ssw0rd 这些,占了真实泄露量的惊人比例。你以为的「创意」,在攻击者眼里早就是公开剧本。


攻击者是怎么破你密码的

  • 撞库(Credential Stuffing):从别处买来/拖库的账号密码,自动批量去各网站试登录。这是「一套密码通用」最致命的原因——你一个账户泄露,所有账户跟着裸奔。
  • 暴力破解 / 字典攻击:短密码、常见单词组合,在普通显卡上几秒到几分钟就能穷举完。一张消费级显卡每秒能试几十亿次哈希。
  • 社会工程与个人信息:生日、名字、宠物、车牌。攻击者只要稍微了解你(或你的社交账号),就能把这些塞进字典优先试。
  • 彩虹表(Rainbow Table):提前算好「常见密码 → 哈希」的对照表,拿到泄露的哈希库直接反查。加盐(salt)能废掉它。

注意这几类的共同前提:你的密码要么太常见,要么太短,要么和你的信息有关。只要避开这三点,破解成本就会高到没人愿意碰你。


什么才是真正的「强」

三个标准,按重要性排序:

  1. 够长:12–16 个字符起步。长度对破解成本的提升是指数级的,比任何「加个符号」都管用。一个 12 位随机密码,比 8 位复杂密码难破几个数量级。
  2. 真随机:字符来自密码学随机数生成器,不是你脑子里编的。人编的密码有明显的模式(比如首字母大写、结尾加数字、用常见单词),熵很低。
  3. 唯一:每个站点不同。这一条单独就能挡住撞库。

不同密码被破解的时间量级(基于离线暴力,仅作直觉参考;实际取决于攻击者算力):

密码 大约破解成本
password123 瞬间
P@ssw0rd1! 字典攻击下几秒
8 位随机字母数字 数小时到数天
12 位随机字母数字符号 数千年以上
4 个随机词组成的口令短语 也上千年

熵:给「强度」一个可量化的标准

密码学里用「熵(entropy,单位 bit)」衡量随机性。粗略公式:熵 ≈ 字符集大小的对数 × 长度

  • 小写字母(26 种):每个字符约贡献 log₂26 ≈ 4.7 bit
  • 加数字(36 种):约 5.17 bit
  • 大小写+数字+符号(约 95 种):约 6.57 bit

所以:

密码 估算熵
8 位复杂字符 ~52 bit
12 位复杂字符 ~79 bit
4 个随机常用词(每词~11bit) ~44–55 bit
5 个随机常用词 ~55–65 bit

经验阈值:熵 ≥ 60 bit 算「强」,≥ 80 bit 算「很强」。这就是为什么口令短语只要词够多、真随机,就能和乱码一样扛揍。


怎么生成:交给工具,别靠脑子

自己想密码,再「随机」也带着习惯。让工具用密码学随机数生成才靠谱:

长度建议直接拉到 16 位以上。多一位,破解成本翻几十倍。下面是正确和错误的生成方式对比:

// ❌ 错误:Math.random 是伪随机,可被预测,别用于密码
const weak = Math.random().toString(36).slice(2, 10);

// ✅ 正确:用 Web Crypto 的密码学随机数
function genPassword(len = 16) {
  const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789';
  const arr = new Uint32Array(len);
  crypto.getRandomValues(arr);
  return Array.from(arr, n => chars[n % chars.length]).join('');
}

口令短语:又好记,又扛揍

如果嫌乱码难记,试试口令短语(Passphrase)——Diceware 思路:挑 4–5 个互不相关的随机词,用分隔符连起来,比如 correct-horse-battery-staple(经典示例)。

它比同等长度的乱码更好记,熵却一点不低:每个常用词约贡献 10–13 bit 熵,5 个词就是 50–65 bit,远超大多数随机短密码。对手写脑记型用户,这是最实用的方案。

别用名言、歌词、或者「把一句话首字连起来」——那依然是可预测的模式。词必须真的是随机选的(用工具的随机词功能,别自己挑)。

进阶:在词之间加随机数字和符号,比如 correct-7-horse-battery-3-staple,熵再上一个台阶,也不难记。


管理:管理器 + 唯一 + 双因素

生成强密码只是第一步,记不住就白搭。

  • 用密码管理器(Bitwarden、1Password、KeePass 等):每个站点存一个唯一强密码,你只守住一个主密码。主密码建议用上面的口令短语思路。好的管理器是零知识架构——你的库在本地加密,服务商也看不到明文。
  • 开双因素(2FA):就算密码泄露,多一道动态码也登不进。TOTP 工具可以生成步步验证码,比短信可靠。
  • 重要账户别只靠短信验证:SIM 互换攻击能劫持短信,能上 TOTP 或硬件密钥(如通行密钥/Passkey)的优先上。

双因素方式的可靠度排序:

方式 安全度 备注
硬件密钥 / Passkey(WebAuthn) 最高 防钓鱼,无密可偷
TOTP 验证器 App 不依赖短信,推荐
短信 SMS 可被 SIM 互换劫持
邮箱验证码 中低 邮箱若泄露则连带失效

开发者视角:秘密怎么存

如果你是写后端的,一条铁律:永远不要明文存密码

哈希,而不是加密

密码应该只存哈希——用 bcrypt / Argon2 / PBKDF2,并且加盐。注意:「哈希」和「加密」不同:加密可逆,哈希不可逆。你不需要(也不应该)能还原用户密码。

工具库提供了哈希工具(MD5/SHA 等摘要)和bcrypt 工具(专门做密码哈希)。重要:MD5/SHA 是通用摘要算法,算得太快,不适合直接存密码——它们挡不住暴力破解。正式存储请用 bcrypt / Argon2 / scrypt 这类「慢哈希」。

// Node.js:用 bcrypt 存密码(正确姿势)
import bcrypt from 'bcrypt';
const saltRounds = 12;                 // 越大越慢越安全,12 是常见值
const hash = await bcrypt.hash(password, saltRounds);
// 存 hash 进数据库,别存 password

// 登录时校验
const ok = await bcrypt.compare(inputPassword, hashFromDb);
// Node.js:用 Argon2(更现代,推荐新项目)
import argon2 from 'argon2';
const hash = await argon2.hash(password, {
  type: argon2.argon2id,
  memoryCost: 65536,   // 64 MB
  timeCost: 3,
  parallelism: 1,
});

盐(salt)、胡椒(pepper)与防爆破

  • :每个用户随机一串,混进哈希,存进数据库。作用是让相同密码产生不同哈希,废掉彩虹表和撞库。bcrypt/Argon2 会自动加盐,直接用即可。
  • 胡椒(pepper):全局一个密钥,不进数据库(放环境变量/密钥管理),在哈希前先拼到密码上。即使数据库泄露,没有 pepper 也难破解。
  • 限速与锁死:登录接口必须限流、失败次数锁定、加验证码,挡住在线暴力。
  • 时序攻击:用「恒定时间比较」校验哈希(bcrypt.compare 内部已做),别用 == 直接比。

需要可逆时再用加密

比如要回推的密钥、用户授权的第三方 token,用AES-256-GCM 工具,口令经 PBKDF2 派生密钥,全程本地。但「用户登录密码」永远不该可逆——那是设计错误。

永远别把用户密码写进日志、别存明文数据库、别在前端做「密码强度」之外的任何处理。前端强度提示只是 UX,真正的安全在后端哈希。


合规参考:NIST 的新思路

美国 NIST 800-63B 早就推翻了「每 30 天强制换密码」「必须包含大小写+数字+符号」的老套路。新建议:

  • 长度优先(至少 8,建议更长),而非强制复杂组合;
  • 不要强制定期更换(没泄露就别换,强制定期换反而催生弱密码);
  • 检查密码是否在已知泄露库中(用 k-anonymity 接口查前缀,不泄露完整密码);
  • 允许粘贴密码(方便用管理器);
  • 限制最大长度即可,别限制特殊字符。

密码强度分析工具的实现思路就参考了这些原则——不只看「有没有符号」,更看长度和是否落入常见模式。


常见错误

错误 后果 正确做法
一套密码通用 一处泄露全崩 每站唯一
P@ssw0rd 式替换 字典秒破 真随机 / 口令短语
写在手机备忘录 手机丢就完 密码管理器
只开短信 2FA SIM 互换可劫持 TOTP / 硬件密钥
用短 PIN 当密码 暴力秒破 12–16+ 字符
后端明文存密码 一泄露全曝光 bcrypt / Argon2 哈希
用 MD5/SHA 直接存密码 快哈希挡不住爆破 用慢哈希算法

常见问题

密码要定期换吗? 没有泄露迹象就不用(遵循 NIST 新指南)。强制每 30 天换一次,反而让人写下弱密码或只改末尾数字。等出现泄露再换。

口令短语和乱码密码哪个好? 都行,关键是长度和随机性。口令短语胜在好记,适合主密码和手写记录;随机乱码适合管理器自动填的站点密码。

发现某站泄露了怎么办? 立刻改掉那个站(以及所有复用同一密码的站)的密码 → 开 2FA → 去 Have I Been Pwned 查自己哪些邮箱中招。

密码管理器的主密码忘了会怎样? 主密码通常无找回机制(这是它安全的代价)。所以主密码一定要用你真正记得住、又够长的口令短语,并留一份离线备份(手写锁进抽屉)。

开发者:用哪个哈希算法? 新项目优先 Argon2id;要兼容老系统用 bcrypt(cost≥12)。避免直接用 MD5/SHA 系列存密码。


账号安全自检清单

1. 有没有重复使用的密码? → 用 /encode/password 生成唯一强密码逐个替换
2. 长度够吗(≥12,建议 16+)? 不够就加长
3. 开了双因素吗? → 优先 TOTP(/utils/totp)或 Passkey,别只靠短信
4. 开发者:密码是哈希存储吗? → /encode/bcrypt,别明文,别用 MD5/SHA
5. 主密码好记又够强吗? → 用口令短语思路,留离线备份
6. 有没有在泄露库里? → 定期查 Have I Been Pwned

把这六条过一遍,你的账号安全等级会比绝大多数人高出一个身位。密码这件事,早一天认真,少一天提心吊胆。相关的图片/文件隐私处理,可以参考数据隐私指南

本站提供浏览器本地工具,免注册即可试用 →

#密码安全#强密码#密码生成器#密码管理器#双因素认证#哈希