un

guest
1 / ?
back to lessons

使存储格式可恢复的因素

四种存储格式,按可恢复性排序:

| 格式 | 可恢复性 | 示例 | 恢复方法 |

|--------|-------------|---------|-----------------|

| 明文 | 是 | password: hunter2 | 读取文件 |

| Base64 | 是 | cGFzc3dvcmQ= | base64 --decode |

| 可逆密文 (AES) | 是 | ENC[AES256:...] | 使用密钥解密 |

| 单向散列 (bcrypt) | 否 | $2b$12$... | 不能逆转;必须暴力破解 |

明文、Base64 和可逆密文:所有都可恢复。一个数据库泄露会将所有密码暴露给攻击者,针对所有用户。一次泄露,全面暴露。

Mailman 2.x 示例

Mailman 2.x (GNU 邮件列表管理器):以明文存储订阅者密码。每月密码提醒邮件:将所有订阅者的密码以明文发送。两次缺陷,均为 MOAD-0006:

1. 存储:列表数据库中以明文存储。服务器被攻破时,会暴露所有订阅者密码。

2. 广播:每月邮件发送明文密码至订阅者邮件服务器。邮件在多个 SMTP 跳转中以明文形式传输。

Mailman 团队设计了这两个行为。恢复是功能:订阅者可以恢复忘记的密码。"玻璃安全箱"一名来自于此:安全箱中存储的凭证以可见形式保存。只要有人到达安全箱,就可以一次性读取所有内容。

已经被盗原则

以可恢复形式存储的凭证已经被盗。攻击者尚未到来。泄露尚未发生。但是,架构保证:当泄露发生时,所有凭证都会同时落入攻击者手中。没有单独发生的泄露;所有以可恢复存储的凭证在同一操作中转移到攻击者。

MOAD-0006 vs MOAD-0004

MOAD-0004 (Logged Secret):凭证意外写入日志。日志写入不是意图;它是为了启用头部日志进行调试而产生的副作用。

MOAD-0006 (Glass Safe):凭证通过设计以可恢复形式存储。恢复是意图。密码提醒功能需要存储密码。显示密码功能需要存储密码。对恢复做出架构承诺,创建了缺陷。

一句话区分:MOAD-0004意外地将凭据放入日志中;MOAD-0006有意地将凭据存储在可恢复的形式中。修复措施在不同层面上操作。

结构性 vs 意外性

MOAD-0006 与 MOAD-0004 之间的架构区别决定了修复策略。意外地写入日志:修复序列化层。为恢复设计的存储:重新设计需要恢复的功能。

Glass Safe 为什么结构上与 MOAD-0004 不同?每个缺陷用一句话描述。修复措施意味着什么?

为什么 bcrypt 工作

单向散列函数接受一个密码并产生一个固定长度的摘要。给定摘要,无法恢复原始密码。不是‘难以恢复’:是不可能逆转的。该函数只运行一个方向。

用于凭据存储所需的三个属性:

1. 单向(预映射抵抗力)。 给定 hash(password), 无法通过算法恢复 password 更快的方式。bcrypt, scrypt & argon2 都满足这个属性。

2. 盐。 在密码前添加一个随机值,然后进行散列。相同密码,不同盐,产生不同的散列。目的是打败彩虹表(预计算的散列字典)。在没有盐的情况下:攻击者只需计算 hash('password123') 一次,然后同时检查1,000,000个用户。有盐的情况下:每个用户都有一个唯一的散列,即使密码相同。

3. 慢设计。 bcrypt 接受工作因子。工作因子越高:迭代次数越多,哈希尝试时间越长。登录:一次哈希需要 300ms。可接受。暴力破解:300ms per attempt。以 1 billion 次尝试为例:9.5 年 per 密码。对于攻击者来说不合适。慢性就是一个特性,不是缺陷。

import bcrypt

# 存储:带盐的一次性哈希
def store_password(plaintext: str) -> bytes:
    return bcrypt.hashpw(plaintext.encode(), bcrypt.gensalt(rounds=12))

# 验证:哈希候选者并比较摘要
def verify_password(plaintext: str, stored_hash: bytes) -> bool:
    return bcrypt.checkpw(plaintext.encode(), stored_hash)

# NEVER 存储:明文密码
# NEVER 恢复:从哈希中恢复明文密码
# 密码重置,不是密码提示

交易-off

一次性哈希使密码恢复不可能。用户忘记密码无法收回密码。无法存在密码提示邮件。用户体验发生变化:'忘记密码?重置它'。这不是降级:是一个安全边界。系统无法恢复密码,因此无法泄露密码。

暴露 bcrypt 哈希的数据库泄露:所有哈希都可见,未泄露任何密码。攻击者必须针对每个哈希单独进行暴力破解,尝试时间为 300ms,每个用户盐使预计算表无效。暴露明文密码的泄露:总体即时暴露。

强大的加密不够

一项安全审计发现了一个凭证存储系统。使用 AES-256-CBC 加密与服务器端密钥存储密码。审计报告将其标记为 Glass Safe 缺陷。

工程团队回应:'AES-256 是可用的最强大的对称密钥加密。密钥存储在硬件安全模块中。没有攻击者可以解密这些密码。'

即使使用了强大的加密,这个问题仍然是 MOAD-0006,为什么?哪个是正确的修复方法?