在現代計算系統中,隨機數無處不在,從生成密碼到玩簡單的抽獎遊戲。然而,在密碼學領域,隨機數的安全性不僅僅是以低概率「中獎」的問題,而是決定系統能否抵禦攻擊的關鍵因素。
如果隨機數生成器不安全,可能會導致:
- 加密密鑰的預測,使系統通信容易被破解;
- 會話令牌的偽造,導致用戶賬戶的非法接管;
- 簽名算法的失效,使數字簽名失去合法性。
因此,在密碼學應用中,我們需要的不僅僅是「看似隨機」的數字序列,還需要不可預測且安全的隨機數。這就是 密碼學安全的偽隨機數生成器 (CSPRNG) 的用武之地。
什麼是 CSPRNG?
CSPRNG 是一種專為密碼學應用設計的偽隨機數生成器 (PRNG),具有更高的安全標準。
CSPRNG 的核心特徵包括:
- 預測抵抗性:攻擊者無法根據已知部分預測隨機序列的其他部分。
- 向後不可追溯性:即使內部狀態被攻擊者竊取,先前生成的隨機數序列也無法被恢復。
為了理解 CSPRNG 的重要性,讓我們將其與其他隨機數生成方法進行比較。
隨機數生成器的比較
-
真隨機數生成器 (TRNG)
TRNG 基於物理現象(例如硬體噪聲、電磁干擾)生成完全隨機的值,但速度較慢且強烈依賴於硬體。
-
偽隨機數生成器 (PRNG)
PRNG 基於算法和種子生成隨機數,效率高但可預測,不適合密碼學場景。
-
CSPRNG
CSPRNG 基於密碼學原理設計,解決了 PRNG 的安全漏洞,確保生成的隨機數序列不可預測。
例如,PRNG 就像是一個自動生成詩句的程序;只要知道起始句(種子),攻擊者就可以預測後續的句子。相比之下,CSPRNG 就像是一個鎖住詩句源代碼的程序,使外界幾乎無法預測下一句。
CSPRNG 的原理和算法
常見的 CSPRNG 算法
-
HMAC 確定性隨機位生成器 (HMAC-DRBG)
基於 HMAC (Hash-based Message Authentication Code) 算法的 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 中的 CryptGenRandom
或 BCryptGenRandom
接口。
常見的編程語言也提供了系統級真隨機數接口的封裝:
- Node.js 的
crypto.randomBytes()
方法; - Java 的
SecureRandom
類; - Python 的
os.urandom()
接口和secrets
模塊等。
你可能會想,既然可以生成系統級的真隨機數,為什麼我們還需要 CSPRNG 算法?
如前所述,操作系統的熵池容量有限,這意味著它生成真隨機數的速度有限。在短時間內需要大量隨機數的場景中,系統級隨機數無法滿足需求。CSPRNG 是對系統級真隨機數的增強,提供更快的密碼學安全隨機數生成,以及更高的定制化和更多的隨機位等。
使用 CSPRNG 時,應注意以下幾點:
- 如果使用普通偽隨機數種子,可能會導致攻擊者預測隨機序列,從而導致 CSPRNG 輸出不安全。我們可以使用前面提到的系統級接口生成真隨機數作為種子。
- 如果 CSPRNG 的內部狀態洩露,也可能導致生成的隨機數被預測。為避免此類情況,我們可以定期更新 CSPRNG 的狀態或種子。
應用示例
密鑰生成
在加密通信中,密鑰的安全性直接決定了系統的安全性。如果密鑰是可預測的,攻擊者可以通過暴力破解或分析密鑰生成模式獲取密鑰,從而解密通信內容。因此,密鑰生成需要極高不可預測性的隨機數,而 CSPRNG 的特性(預測抵抗性和向後不可追溯性)確保了生成的密鑰難以預測。
會話令牌
在 Web 應用中,會話令牌用於識別用戶會話(如登錄狀態)。如果令牌被攻擊者猜測或偽造,可能會導致會話劫持 (Session Hijacking),從而冒充用戶進行操作。
例如,在 CSRF 和 PKCE 中,使用隨機的 state
或 code
來防止會話或流程攻擊。
還有其他場景,例如在使用哈希算法處理要寫入 DB 的密碼時,如果僅使用簡單的哈希算法,難以抵抗彩虹表攻擊。在這種情況下,使用哈希算法時,會添加 Salt 作為隨機變量,使得相同的密碼生成不同的哈希值。