Logo Logo
GitHub Designed by Logto

在现代计算系统中,随机数无处不在,从生成密码到玩简单的彩票游戏。然而,在密码学领域,随机数的安全性不仅仅是以低概率“中奖”的问题,而是决定系统能否抵御攻击的关键因素。

如果随机数生成器不安全,可能导致:

  • 加密密钥的预测,使系统通信容易被破解;
  • 会话令牌的伪造,导致用户账户的非法接管;
  • 签名算法的失效,使数字签名失去合法性。

因此,在密码学应用中,我们需要的不仅仅是“看似随机”的数字序列,还需要不可预测且安全的随机数。这就是 密码学安全伪随机数生成器 (CSPRNG) 的用武之地。

什么是 CSPRNG?

CSPRNG 是一种专为密码学应用设计的伪随机数生成器 (PRNG),具有更高的安全标准。

CSPRNG 的核心特性包括:

  1. 预测抵抗性:攻击者无法根据已知部分预测随机序列的其他部分。
  2. 向后不可追溯性:即使内部状态被攻击者窃取,先前生成的随机数序列也无法恢复。

为了理解 CSPRNG 的重要性,让我们将其与其他随机数生成方法进行比较。

随机数生成器的比较

  1. 真随机数生成器 (TRNG)

    TRNG 基于物理现象(例如硬件噪声、电磁干扰)生成完全随机的值,但速度慢且强烈依赖于硬件。

  2. 伪随机数生成器 (PRNG)

    PRNG 基于算法和种子生成随机数,效率高但可预测,不适合密码学场景。

  3. CSPRNG

    CSPRNG 基于密码学原理设计,解决了 PRNG 的安全漏洞,确保生成的随机数序列不可预测。

例如,PRNG 就像一个自动生成诗句的程序;只要知道起始句(种子),攻击者就可以预测后续句子。相比之下,CSPRNG 就像一个锁定诗句源代码的程序,使外界几乎无法预测下一句。

CSPRNG 的原理和算法

常见的 CSPRNG 算法

  • HMAC 确定性随机位生成器 (HMAC-DRBG)

    基于 HMAC (基于哈希的消息认证码) 算法的 CSPRNG,使用密钥和伪随机值更新内部状态。HMAC-DRBG 通过双状态管理(密钥 K 和伪随机值 V)提高了不可预测性和向后不可追溯性。

  • 基于 SHA-256 的 PRNG

    基于 SHA-256 哈希算法的随机数生成器,不需要额外的密钥,仅依赖于状态值。其更新机制简单,但抵抗攻击的能力不如 HMAC-DRBG。

  • 计数器模式确定性随机位生成器 (CTR-DRBG)

    基于分组密码模式(如 AES)的随机数生成器,使用计数器 (CTR) 模式生成随机数。适用于高性能和高安全需求场景,依赖于分组密码算法的安全性,适合硬件实现。

随机种子生成

  • 通过调用操作系统的真随机数生成器 (TRNG) 获取高熵种子。
  • 使用硬件安全模块 (HSM) 或系统熵源(如 /dev/urandom)生成种子,以确保 CSPRNG 初始状态的随机性。

如何使用 CSPRNG?

从前面的原理中我们知道,为了确保 CSPRNG 的有效性,我们应该从一个真正的随机种子开始。如果初始种子不能保证真正的随机性,那么理论上仅依靠 CSPRNG 算法很难确保随机数的真正密码学安全。

事实上,现代操作系统已经考虑到了这个问题,并提供了系统级的真随机数接口,这些接口大多基于底层熵源(如硬件噪声、键盘和鼠标事件)生成高质量的随机数。

例如,Linux 和 macOS 中的 /dev/random/dev/urandom 接口,以及 Windows 中的 CryptGenRandomBCryptGenRandom 接口。

常见的编程语言也提供了系统级真随机数接口的封装:

  • Node.js 的 crypto.randomBytes() 方法;
  • Java 的 SecureRandom 类;
  • Python 的 os.urandom() 接口和 secrets 模块等。

你可能会问,既然可以生成系统级的真随机数,为什么我们还需要 CSPRNG 算法?

如前所述,操作系统的熵池容量有限,这意味着它生成真随机数的速度有限。在短时间内需要大量随机数的场景中,系统级随机数无法满足要求。CSPRNG 是对系统级真随机数的增强,提供更快的密码学安全随机数生成,以及更高的定制化和更多的随机位等。

使用 CSPRNG 时,应注意以下几点:

  • 如果使用普通的伪随机数种子,可能导致攻击者预测随机序列,导致 CSPRNG 输出不安全。我们可以使用前面提到的系统级接口生成真随机数作为种子。
  • 如果 CSPRNG 的内部状态泄露,也可能导致生成的随机数被预测。为避免这种情况,我们可以定期更新 CSPRNG 的状态或种子。

应用示例

密钥生成

在加密通信中,密钥的安全性直接决定了系统的安全性。如果密钥是可预测的,攻击者可以通过暴力破解或分析密钥生成模式获得密钥,从而解密通信内容。因此,密钥生成需要极高不可预测性的随机数,而 CSPRNG 的特性(预测抵抗性和向后不可追溯性)确保生成的密钥难以预测。

会话令牌

在 Web 应用中,会话令牌用于标识用户会话(如登录状态)。如果令牌被攻击者猜测或伪造,可能导致会话劫持 (Session Hijacking),从而冒充用户进行操作。

例如,在 CSRF 和 PKCE 中,使用随机的 statecode 来防止会话或流程攻击。

还有其他场景,例如在使用哈希算法处理要写入 DB 的密码时,如果仅使用简单的哈希算法,很难抵御彩虹表攻击。在这种情况下,使用哈希算法时,添加一个随机变量 Salt,使相同的密码生成不同的哈希值。