近年来,密码策略经历了根本性的转变。旧规则 — 强制特殊字符、强制 90 天轮换、安全问题 — 已被 NIST(美国国家标准与技术研究院)正式废弃。取而代之的是基于证据的新方法,重点关注长度、泄露列表检查和多因素认证。本综合指南涵盖了 2025 年现代密码要求的所有知识,从最新的 NIST SP 800-63B 指南到实际实施策略。
1. NIST SP 800-63B:发生了什么变化
NIST 特别出版物 800-63B(数字身份指南:认证和生命周期管理)于 2017 年首次修订,并在 2024 年持续更新。它从根本上改变了组织应该如何思考密码安全。关键洞察:大多数传统密码规则使密码对人类更难记忆,但对攻击者来说并没有明显增加破解难度。
NIST 明确指出,验证方不得要求定期更改密码,除非有证据表明密码已泄露。研究表明,强制轮换导致可预测的模式:用户附加递增数字(Password1、Password2、Password3)或做出攻击者容易猜到的最小更改。未泄露的强密码不会随时间变弱。
NIST 取消了对特定字符类型(大写、小写、数字、特殊字符)的要求。这些规则导致了可预测的模式,如 "Password1!" — 满足所有传统复杂性要求,但极易被猜到。NIST 转而强调长度和已知泄露密码的检查。
诸如"你母亲的娘家姓是什么?"之类的安全问题不再被接受。这些信息通常可以公开获取或容易猜到。NIST 要求验证方不得使用基于知识的认证(KBA)进行验证。
当用户设置或更改密码时,NIST 要求将密码与常用、预期或已泄露值列表进行比较。这包括来自先前泄露数据库的密码、字典单词、重复或顺序字符,以及上下文特定的词(如服务名称或用户名)。
# NIST SP 800-63B Summary of Key Changes
┌─────────────────────────────────────────────────────────────────────┐
│ REMOVED (SHALL NOT) │ ADDED (SHALL / SHOULD) │
├───────────────────────────────────┼─────────────────────────────────┤
│ Forced periodic rotation │ Check against breach lists │
│ Composition rules (upper+lower │ Minimum 8 chars (12+ better) │
│ +digit+special) │ Allow 64+ character passwords │
│ Password hints │ Accept all Unicode + spaces │
│ Security questions (KBA) │ Allow paste in password fields │
│ Truncating passwords │ Offer "show password" option │
│ SMS as primary 2FA (restricted) │ Use approved hash algorithms │
└───────────────────────────────────┴─────────────────────────────────┘2. 最小长度:8 位已过时,12-16 位是新标准
NIST SP 800-63B 要求用户选择的密码最少 8 个字符,但安全专家和现代框架已经远远超过这个底线。数学现实很简单:每增加一个字符,攻击者必须覆盖的搜索空间就呈指数级增长。
以下是在假设 95 个可打印 ASCII 字符且攻击者以每秒 100 亿次尝试(现代 GPU 集群对快速哈希)进行暴力破解时,密码长度如何影响暴力破解时间:
| 密码长度 | 可能的组合数 | 暴力破解时间 | 评级 |
|---|---|---|---|
| 6 字符 | 95^6 = 7350 亿 | ~1.2 分钟 | 瞬间可破解 |
| 8 字符 | 95^8 = 6.6 千万亿 | ~7.6 天 | 2025 年已太弱 |
| 10 字符 | 95^10 = 59.9 百京 | ~190 年 | 最低可接受 |
| 12 字符 | 95^12 = 540 十垓 | ~170 万年 | 良好 |
| 16 字符 | 95^16 = 44 涧 | ~139 万亿年 | 优秀 |
| 20 字符 | 95^20 = 3.6 x 10^39 | ~11.4 x 10^21 年 | 极致(但很好) |
Note: 重要:这些计算假设使用 SHA-256 等快速哈希。使用 Argon2id 等适当的密码哈希算法(将攻击者速度降低到约每秒 1,000 次哈希),即使 8 字符的密码也需要更长时间。然而,长度仍然是对抗暴力破解攻击最有效的防御。
各组织的现代建议:
- NIST SP 800-63B:最少 8 字符(但建议允许最多 64 字符以上)
- OWASP:最少 8 字符,建议 12 字符以上
- PCI-DSS v4.0:最少 12 字符(从 v3.2 的 7 字符提高)
- Microsoft:Azure AD 最少 12 字符
- Google:最少 8 字符,建议 12 字符以上
2025 年最佳实践:将最小长度设为 12 字符。允许(并鼓励)64 字符或更多。永远不要截断密码。
3. NIST 推荐什么:允许所有字符、检查泄露列表、无提示
NIST 指南采取了与传统密码策略根本不同的方法。它们不是让密码难以创建,而是专注于让密码难以猜测。
验证方应接受所有可打印 ASCII 字符、空格字符和所有 Unicode 字符(包括表情符号)。不得有限制哪些字符可以出现在何处的规则。这使得密码短语、非英语密码和创造性密码构造成为可能。
验证方应允许密码长度至少 64 个字符。没有理由将上限设置在此以下。应通过 UI 设计鼓励更长的密码 — 显示奖励长度而非复杂性的密码强度指示器。
当用户创建或更改密码时,将其与已知泄露密码列表进行比较。如果密码出现在泄露数据库中,拒绝它并解释原因。Have I Been Pwned API 提供了一种免费的、保护隐私的方式,使用 k-匿名性来实现这一点。
验证方不得截断密码。用户输入的每个字符都必须成为存储哈希的一部分。Bcrypt 有 72 字节的限制 — 如果使用 bcrypt,在传递给 bcrypt 之前先用 SHA-256 对密码进行预哈希。
验证方不得使用密码提示、安全问题或基于知识的认证。这些提供了削弱密码安全性的攻击向量。改用基于电子邮件或基于 MFA 的账户恢复。
验证方应允许用户在输入时临时显示(取消遮蔽)密码。这减少了隐藏输入导致的错误,帮助用户正确创建和输入长而复杂的密码。
4. NIST 移除了什么:强制特殊字符、定期过期、安全问题
理解被移除的内容与理解被添加的内容同样重要。每个被移除的要求都基于研究证明是错误的假设。
要求至少包含一个大写字母、一个小写字母、一个数字和一个特殊字符的旧要求导致了完全可预测的模式。"Password1!" 满足所有传统复杂性规则,却是最常见的泄露密码之一。用户绝大多数将大写字母放在首位、数字放在末尾附近、特殊字符放在最后。攻击者知道这一点并据此优化破解策略。
强制用户每 30、60 或 90 天更改密码会导致安全疲劳和可预测的密码变异。卡内基梅隆大学的研究发现,被迫更改密码的用户选择的密码在统计上与之前的密码相似,使其容易受到定向猜测攻击。NIST 现在说:仅在有泄露证据时才更改密码。
安全问题从根本上就是有缺陷的。"你母亲的娘家姓是什么?"或"你出生在哪个城市?"等问题的答案通常可以通过社交媒体、公共记录或数据泄露公开获取。即使是"秘密"问题,如"你最喜欢的电影是什么?"也有令人惊讶的小答案空间。Google 的研究表明,19.7% 的英语使用者会对"你最喜欢的食物是什么?"回答"pizza"。
虽然 NIST 没有完全移除 SMS 2FA,但由于已知漏洞(SIM 卡交换、SS7 协议攻击、对运营商员工的社会工程),它被归类为"受限"认证方式。NIST 建议使用基于应用的 TOTP 或硬件安全密钥。
模式很清楚:NIST 移除了那些在给合法用户增加摩擦的同时制造虚假安全感的要求。每个被移除的规则都被实际改善安全性的循证指导所取代。
5. 熵计算器:如何以比特为单位估计密码强度
密码熵以比特为单位衡量密码的不可预测性。更高的熵意味着密码更难猜测。熵的计算公式为:H = log2(R^L),其中 R 是字符池的大小,L 是密码长度。
# Password Entropy Formula
H = log2(R^L) = L * log2(R)
Where:
H = Entropy in bits
R = Size of the character pool
L = Password length
# Example: 12-character password using full ASCII (95 chars)
H = 12 * log2(95) = 12 * 6.57 = 78.8 bits
# Example: 4-word Diceware passphrase (7776-word list)
H = 4 * log2(7776) = 4 * 12.92 = 51.7 bits字符池大小
| 字符池 | 大小 (R) | 示例 |
|---|---|---|
| 仅数字 (0-9) | 10 | 0-9 |
| 小写字母 (a-z) | 26 | a-z |
| 大小写字母 (A-Za-z) | 52 | A-Za-z |
| 字母数字 (A-Za-z0-9) | 62 | A-Za-z0-9 |
| 完整可打印 ASCII | 95 | !-~, space |
| Diceware 词表 | 7,776 | correct, horse, battery... |
常见密码类型的熵计算
| 密码类型 | 长度 | 熵计算公式 | 熵(比特) | 强度 |
|---|---|---|---|---|
| 4 位 PIN | 4 | log2(10^4) | 13.3 比特 | 非常弱 |
| 6 字符小写 | 6 | log2(26^6) | 28.2 比特 | 弱 |
| 8 字符混合大小写+数字 | 8 | log2(62^8) | 47.6 比特 | 中等 |
| 12 字符完整 ASCII | 12 | log2(95^12) | 78.8 比特 | 强 |
| 16 字符完整 ASCII | 16 | log2(95^16) | 105.1 比特 | 非常强 |
| 4 词密码短语 (Diceware) | 4 个词 | log2(7776^4) | 51.7 比特 | 中等 |
| 6 词密码短语 (Diceware) | 6 个词 | log2(7776^6) | 77.5 比特 | 强 |
| 8 词密码短语 (Diceware) | 8 个词 | log2(7776^8) | 103.4 比特 | 非常强 |
注意:这些计算假设密码是真正随机生成的。人类选择的密码有效熵要低得多,因为人类是可预测的 — 他们使用字典词、名字、日期和常见替换(a→@、e→3)。仅检查长度和字符类别的密码强度计会大大高估人类选择密码的熵。
2025 年目标熵级别:
- 在线攻击(限速):有账户锁定的情况下 30+ 比特就足够
- 离线攻击(被盗哈希,快速哈希):至少 60+ 比特
- 离线攻击(被盗哈希,Argon2id):40+ 比特可以接受
- 高安全账户:建议 80+ 比特
6. 对比表:NIST vs OWASP vs PCI-DSS vs 旧标准
不同的标准和框架有不同的要求。以下是截至 2025 年的比较:
| 要求 | NIST SP 800-63B (2024) | OWASP ASVS v4.0 | PCI-DSS v4.0 | 传统(2017 年前) |
|---|---|---|---|---|
| 最小长度 | 8 字符 | 8 字符(建议 12+) | 12 字符 | 6-8 字符 |
| 最大长度 | 64+ 字符 | 128+ 字符 | 未指定 | 通常 16-20 字符 |
| 复杂性规则 | 不得要求 | 不要求 | 数字 + 字母 | 大写 + 小写 + 数字 + 特殊字符 |
| 强制轮换 | 不得要求 | 不建议 | 每 90 天(无 MFA 时) | 每 30-90 天 |
| 泄露列表检查 | 必须检查 | 必需 | 不要求 | 不要求 |
| MFA | AAL2+ 必需 | Level 2+ 必需 | 管理员访问必需 | 可选 |
| 密码提示 | 不得使用 | 禁止 | 未涉及 | 常用 |
| 密码哈希 | 仅限批准的算法 | Argon2id、bcrypt、scrypt | 强单向哈希 | MD5 或 SHA-1 常见 |
| Unicode 支持 | 必须接受 | 必需 | 未涉及 | 通常仅 ASCII |
关键要点:NIST 以最现代、基于证据的方法引领潮流。PCI-DSS v4.0 仍然要求复杂性规则和定期轮换(除非使用 MFA),反映了其对基于研究建议的较慢采纳。如果你只能遵循一个标准,选择 NIST SP 800-63B。
7. 密码短语 vs 密码:为什么 "correct horse battery staple" 胜出
著名的 XKCD 漫画(#936)有力地支持了密码短语优于传统密码的观点。数学支持这一点:从 7,776 个词的 Diceware 列表中随机选择的 4 个词的密码短语具有 51.7 比特的熵 — 与随机的 8 字符混合大小写字母数字密码相当 — 同时更容易记忆。
密码短语与传统密码比较
| 类型 | 示例 | 熵 | 可记忆性 | 输入便捷性 |
|---|---|---|---|---|
| 传统复杂密码 | j7#Kp!2x | ~52 比特 | 非常难 | 慢、易出错 |
| 4 词 Diceware | correct horse battery staple | ~52 比特 | 容易 | 快速、自然 |
| 6 词 Diceware | atlas usable flock dizzy clout snare | ~78 比特 | 中等 | 快速、自然 |
| 8 词 Diceware | embody quote cider clap virus gag yoyo wheat | ~103 比特 | 较难 | 快速、自然 |
密码短语更好的原因:
- 相等或更大的熵:4 个词的密码短语在熵方面与 8 字符的随机密码相当。6 个词的密码短语超过大多数传统密码。
- 更容易记忆:人类更擅长记住词语序列而非随机字符。密码短语创造了心理图像。
- 更容易输入:特别是在移动设备上,输入单词比在字符类型之间切换更快且更不容易出错。
- 抵抗肩窥:一长串单词比短的随机字符串更难从短暂一瞥中记住。
- 自然很长:即使 4 个词的密码短语通常也有 20+ 字符,提供了对暴力破解攻击的出色保护。
Warning: 警告:密码短语的词语必须是随机选择的,而不是由用户选择的。用户选择的短语如 "iloveyouforever" 或 "letmeinplease" 的熵极低,因为攻击者知道常见短语。使用 Diceware 词表配合实际骰子或加密安全的随机数生成器。
如何生成 Diceware 密码短语:
- 获取一个 Diceware 词表(7,776 个词,每个对应一个 5 位骰子数)。
- 为每个需要的词掷 5 个骰子(或 1 个骰子掷 5 次)。
- 在词表中查找每个 5 位数字。
- 用空格组合这些词。这就是你的密码短语。
- 对于大多数用途,5-6 个词提供出色的安全性(64.6 - 77.5 比特)。
# Diceware passphrase generation example
$ dice rolls: 1-6-2-3-4 → "atlas"
$ dice rolls: 5-4-1-1-6 → "usable"
$ dice rolls: 2-5-3-1-2 → "flock"
$ dice rolls: 2-1-4-6-5 → "dizzy"
Passphrase: "atlas usable flock dizzy"
Entropy: 4 * log2(7776) = 51.7 bits
Length: 24 characters (spaces included)
# Compare to traditional password
"j7#Kp!2x" = 8 chars * log2(95) = 52.6 bits
# Same entropy, but much harder to remember and type!8. 实施密码策略:Bcrypt 成本、速率限制、MFA
了解指南是一回事;正确实施是另一回事。以下是在 2025 年实施符合 NIST 标准的现代密码策略的实用清单。
密码哈希
选择 Argon2id 作为主要哈希算法。如果 Argon2id 不可用,使用成本因子 12 或更高的 bcrypt。在生产硬件上目标每次哈希 200-500ms。永远不要使用 MD5、SHA-1、SHA-256 或任何快速哈希函数进行密码存储。
// Argon2id configuration (OWASP recommended)
const argon2 = require('argon2');
const hashConfig = {
type: argon2.argon2id,
memoryCost: 19456, // 19 MiB
timeCost: 2, // 2 iterations
parallelism: 1, // 1 thread
};
// Hash on registration
const hash = await argon2.hash(password, hashConfig);
// Verify on login
const isValid = await argon2.verify(hash, password);
// ── Bcrypt alternative (if Argon2 unavailable) ──
const bcrypt = require('bcrypt');
const COST_FACTOR = 12; // Target: 200-500ms
const bcryptHash = await bcrypt.hash(password, COST_FACTOR);
const bcryptValid = await bcrypt.compare(password, bcryptHash);速率限制
在认证端点实施速率限制以防止在线暴力破解攻击。在 5-10 次失败尝试后,引入渐进延迟或临时账户锁定。在 3 次失败尝试后使用 CAPTCHA。实施基于 IP 的速率限制(例如每个 IP 每小时 100 次尝试)和基于账户的速率限制(例如每个账户每 15 分钟 10 次尝试)。
// Rate limiting example (Express.js with express-rate-limit)
const rateLimit = require('express-rate-limit');
// IP-based rate limiting
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 10, // 10 attempts per IP per window
message: 'Too many login attempts. Please try again later.',
standardHeaders: true,
legacyHeaders: false,
});
// Account-based rate limiting (in-memory example)
const accountAttempts = new Map();
async function checkAccountRateLimit(username) {
const key = username.toLowerCase();
const attempts = accountAttempts.get(key) || { count: 0, lastAttempt: 0 };
if (attempts.count >= 5) {
const cooldown = 15 * 60 * 1000; // 15 minutes
if (Date.now() - attempts.lastAttempt < cooldown) {
throw new Error('Account temporarily locked. Try again later.');
}
attempts.count = 0; // Reset after cooldown
}
return attempts;
}
app.post('/login', loginLimiter, async (req, res) => {
const { username, password } = req.body;
const attempts = await checkAccountRateLimit(username);
const isValid = await verifyPassword(username, password);
if (!isValid) {
attempts.count++;
attempts.lastAttempt = Date.now();
accountAttempts.set(username.toLowerCase(), attempts);
return res.status(401).json({ error: 'Invalid credentials' });
}
accountAttempts.delete(username.toLowerCase());
// ... generate session / JWT
});多因素认证 (MFA)
MFA 是对抗基于凭证攻击最有效的单一防御。即使攻击者获得了密码(通过网络钓鱼、泄露重用或暴力破解),MFA 也能阻止未授权访问。优先选择基于应用的 TOTP(Google Authenticator、Authy)或硬件密钥(YubiKey、Passkeys),而非基于 SMS 的 2FA。
服务端验证清单
Bcrypt / Argon2id 成本调优
成本参数应根据你的特定硬件进行调优。在生产服务器上运行基准测试,选择使每次哈希耗时 200-500ms 的成本。这在用户体验(登录延迟)和攻击者成本之间提供了良好的平衡。
# Benchmarking password hashing on your server
# Goal: 200-500ms per hash
# Node.js benchmark script
const argon2 = require('argon2');
const bcrypt = require('bcrypt');
async function benchmark() {
const password = 'benchmarkPassword123';
// Argon2id benchmarks
for (const mem of [19456, 47104, 65536]) {
const start = Date.now();
for (let i = 0; i < 10; i++) {
await argon2.hash(password, {
type: argon2.argon2id,
memoryCost: mem,
timeCost: 2,
parallelism: 1,
});
}
const avg = (Date.now() - start) / 10;
console.log(`Argon2id (m=${mem}): ${avg.toFixed(0)}ms`);
}
// Bcrypt benchmarks
for (const cost of [10, 11, 12, 13, 14]) {
const start = Date.now();
for (let i = 0; i < 10; i++) {
await bcrypt.hash(password, cost);
}
const avg = (Date.now() - start) / 10;
console.log(`Bcrypt (cost=${cost}): ${avg.toFixed(0)}ms`);
}
}
benchmark();
# Expected output (varies by hardware):
# Argon2id (m=19456): ~150ms
# Argon2id (m=47104): ~350ms ← Good target
# Argon2id (m=65536): ~500ms
# Bcrypt (cost=10): ~75ms
# Bcrypt (cost=11): ~150ms
# Bcrypt (cost=12): ~300ms ← Good target
# Bcrypt (cost=13): ~600ms
# Bcrypt (cost=14): ~1200ms9. 检查泄露数据库:Have I Been Pwned API、k-匿名性
NIST 最具影响力的要求之一是检查密码是否在已知泄露数据库中。Have I Been Pwned (HIBP) 密码 API 使用一种称为 k-匿名性的技术,使这一过程既实用又保护隐私。
k-匿名性如何工作
HIBP 密码 API 从不查看实际密码甚至完整哈希。相反,它使用基于 SHA-1 哈希前 5 个字符的范围搜索:
- 用 SHA-1 对密码进行哈希(仅用于查找,不用于存储)。
- 仅将十六进制编码哈希的前 5 个字符发送到 HIBP API。
- API 返回所有匹配 5 字符前缀的哈希后缀(通常 500-800 个结果)。
- 在本地将完整哈希与返回的后缀进行比较。
- 如果找到匹配,则该密码已在泄露中出现。拒绝它。
// Check password against Have I Been Pwned API (Node.js)
const crypto = require('crypto');
async function isPasswordBreached(password) {
// Step 1: SHA-1 hash the password
const sha1 = crypto.createHash('sha1')
.update(password)
.digest('hex')
.toUpperCase();
// Step 2: Split into prefix (5 chars) and suffix
const prefix = sha1.substring(0, 5);
const suffix = sha1.substring(5);
// Step 3: Query the HIBP API with only the prefix
const response = await fetch(
`https://api.pwnedpasswords.com/range/${prefix}`,
{
headers: { 'Add-Padding': 'true' } // Prevents response-length analysis
}
);
const text = await response.text();
// Step 4: Check if our suffix appears in the results
const lines = text.split('\n');
for (const line of lines) {
const [hashSuffix, count] = line.split(':');
if (hashSuffix.trim() === suffix) {
return {
breached: true,
count: parseInt(count.trim(), 10), // How many times seen
};
}
}
return { breached: false, count: 0 };
}
// Usage in password validation
async function validatePassword(password, username) {
// Check length
if (password.length < 12) {
return { valid: false, reason: 'Password must be at least 12 characters.' };
}
// Check against username / email
if (password.toLowerCase().includes(username.toLowerCase())) {
return { valid: false, reason: 'Password must not contain your username.' };
}
// Check against breach database
const breach = await isPasswordBreached(password);
if (breach.breached) {
return {
valid: false,
reason: `This password has appeared in ${breach.count.toLocaleString()} data breaches. Please choose a different password.`,
};
}
return { valid: true };
}Privacy: 隐私保证:API 只看到匹配数百个不同密码的 5 字符哈希前缀。它永远不会知道检查的是哪个具体密码。完整的哈希比较完全在你的服务器上进行。
截至 2025 年,HIBP 密码数据库包含超过 9 亿个唯一的已泄露密码。如果用户尝试设置出现在此列表中的密码,应该用清晰的解释拒绝它。
HIBP 的替代方案
10. 密码管理器推荐
随着密码变得更长且更独特(从不在站点间重复使用),密码管理器不再是可选的 — 它们是必需的。密码管理器为每个账户生成、存储和自动填充强大的唯一密码。
为什么密码管理器至关重要:
- 普通人有 100 多个在线账户。没有人能记住 100 个独特的强密码。
- 密码重用是基于凭证泄露的首要原因。密码管理器完全消除了重用。
- 密码管理器生成具有最大熵的真正随机密码,而非人类可预测的模式。
- 自动填充防止网络钓鱼:密码管理器不会在相似的钓鱼域名上填充凭证。
| 功能 | 选择标准 |
|---|---|
| 零知识架构 | 服务无法读取你的密码。所有内容都使用你的主密码在本地加密。 |
| 跨平台同步 | 在所有设备(桌面、移动、浏览器扩展)上运行,无缝同步。 |
| 泄露监控 | 当存储的密码出现在数据泄露中时发出警告。 |
| 安全密码生成 | 内置随机密码和密码短语生成器,可配置长度和字符集。 |
| 紧急访问 | 允许受信任的联系人在你丧失能力时访问你的保管库。 |
| 开源/已审计 | 代码可公开审查,并已由安全公司进行独立审计。 |
Tip: 主密码提示:你的密码管理器的主密码是你必须记住的唯一密码。使用 5-6 个词的 Diceware 密码短语(77+ 比特熵)。写下来并存放在实体保险箱中,直到你记住为止。不要以数字方式存储它。
For Developers: 对于开发应用的开发者:不要对抗密码管理器。确保你的登录表单使用标准 HTML 输入类型(<input type="password">)和 autocomplete 属性(登录用 autocomplete="current-password",注册用 autocomplete="new-password")。永远不要禁用密码字段的粘贴功能。
11. 常见问题
2025 年 8 字符密码还可以接受吗?
从技术上讲,NIST SP 800-63B 将 8 字符设为用户选择的记忆密码的绝对最低要求。然而,大多数现代框架(PCI-DSS v4.0、Microsoft、Google)已将 12 字符作为最低要求。即使使用完整 ASCII,8 字符密码也只有约 52 比特的熵,对于使用现代硬件的离线攻击来说安全性有限。我们建议 2025 年任何新应用的最低要求为 12 字符。
我还应该要求密码中包含特殊字符吗?
不应该。NIST 明确指出验证方不得施加要求特定字符类型的组合规则。这些规则导致可预测的模式("Password1!"),给用户增加摩擦而不会有意义地提高安全性。相反,强制执行 12 字符以上的最小长度并检查泄露数据库。允许用户包含任何他们想要的字符,但不要求特定类型。
应该多久强制用户更改一次密码?
除非有泄露证据,否则永远不要。NIST SP 800-63B 指出验证方不得要求定期密码更改。研究一致表明,强制轮换导致更弱的密码(可预测的变异)和安全疲劳。密码只应在有具体原因时更改:已知泄露、可疑账户活动,或用户自愿想要更改。
2025 年最好使用哪种密码哈希算法?
Argon2id 是当前的黄金标准,被 OWASP 推荐为首选。配置至少 19 MiB 内存(m=19456)、2 次迭代(t=2)和 1 个线程(p=1)。如果你的框架中没有 Argon2id,使用成本因子 12 或更高的 bcrypt。永远不要使用 MD5、SHA-1 或 SHA-256 进行密码存储 — 这些是通用哈希函数,不是密码哈希算法。
Passkeys 会完全取代密码吗?
Passkeys(基于 FIDO2/WebAuthn)是认证领域的重大进步,正在被主要平台(Apple、Google、Microsoft)采用。它们通过使用绑定到设备的公钥加密完全消除密码。然而,密码将与 passkeys 共存多年。许多服务仍然需要基于密码的认证作为后备,而 passkey 支持尚未普及。目前,应在强密码策略的同时实施 passkey 支持,而不是用一个替换另一个。
如何说服我的组织采用 NIST 指南?
展示证据:(1) NIST 是美国安全标准的权威机构,在全球受到广泛尊重。(2) 来自卡内基梅隆大学、Google 和 Microsoft 的研究确认传统密码规则降低了安全性。(3) 旧规则增加了支持成本(密码重置是排名第一的帮助台电话)。(4) 主要公司(Apple、Google、Microsoft)已经采用了这些指南。(5) PCI-DSS v4.0 在使用 MFA 时取消了强制轮换要求,显示了行业趋同。将其定义为成本降低和安全改善,而不仅仅是策略变更。