淺談常見的安全亂數產生函式
密碼學上有所謂的「安全偽亂數生成器(CSPRNG)」,常被運用於加解密函式中產生安全金鑰之用,實作上有硬體生成也有軟體生成。本文主要探討一下軟體生成常見的安全(偽)亂數產生函式。
如同我國經濟部工業局委託「行動應用資安聯盟」所推動的「行動應用APP基本資安檢測基準」(簡稱MAS基準),其中的「基準4.1.2.3.6:敏感性資料應採用適當且有效之金鑰長度與加密演算法,進行加密處理再儲存」的基準(2)所定義的:
基準(2) 檢查行動應用程式所使用之加密函式之金鑰是否採用符合ANSI X9.17、FIPS 140–2、NIST SP800–22及SP 800–90A(CAVP Testing:Random Number Generators)至少其中一項之安全的亂數產生函式。
所謂的安全亂數產生函式究竟安不安全,可不是自己說了算,通常還要能符合國際的資安標準如 ANSI X9.17、FIPS 140–2、NIST SP 800–22 及 SP 800–90A等規範才夠安全。以下分為 Android 和 Apple(iOS) 常見的安全亂數產生函式來作探討。
Android常見的安全亂數產生函式
1. SecureRandom (符合FIPS 140–2)
其實於 Android (JAVA)環境中,最常見的安全亂數產生函式只有一個,就是這個 SecureRandom(),這在 JAVA 官方 API 或 Android 官方 API 都已經註明了他是符合 FIPS 140–2的資安標準,就放心使用吧。
2. randomUUID (符合FIPS 140–2)
嚴格來說 UUID 是用於電腦體系中以辨識資訊的一個128位元識別碼,原本並不是當作產生安全亂數的函式之用,但測試時反組譯別人寫的App常發現,也很常有開發者用這個來產生隨機字串。查了一下 randomUUID() 的原始程式碼,也是採用 SecureRandom() 來實作亂數產生,所以理論上勉強也算是足夠安全了。
iOS常見的安全亂數產生函式
1. arc4random系列 (符合NIST 800–90A)
arc4random 系列含 arc4random(), arc4random_buf(), arc4random_uniform() 等,深入研究他實作的原始程式碼後,發現是符合 NIST 800–90A 資安標準的。
從他們的原始程式碼中可以發現都採用ccdrbg_generate()函式實作,再去查找其實作關鍵函式 ccdrbg_generate() Header 的原始程式碼,找到符合 NIST 800–90A 的佐證。
2. SecRandomCopyBytes, SecRandomRef 系列 (符合NIST 800–90A)
這其實是目前 Apple 官方最推薦的使用的安全亂數產生函式,也表明了會持續更新它的安全性。於 Apple 官網 API 就開宗明義地宣稱他是密碼學定義上的安全亂數產生函式,官網討論區也有相關描述,是符合 NIST SP800–90A 資安標準的。
3. /dev/random, /dev/urandom 系列 (符合FIPS 140–2)
早期的 iOS 版本尚不支援上述的安全亂數產生函式,就會採用這個方式產生亂數,現在已經不再推薦直接使用,而建議改採 SecRandomCopyBytes()。採這個方式其實是呼叫 Linux OS 的底層實作,常見於各種 Linux OS 所開發的系統。FIPS 140–2 Security Policy 官方文件即有提到它,於 Apple 官網也有說其 CPRNG 是基於 /dev/random 的實作,所以是符合 FIPS 140–2 的資安標準。
4. Apple corecrypto Module (符合FIPS 140–2, FIPS 140–3)
這是 Apple 官方開發出的一套嵌入式的硬體加密編譯模組,Apple 官網也說明了 Apple corecrypto Module 於2019年即通過 FIPS 140–2 驗證,其提供的 DRBG 亂數產生方式,是經 FIPS 140–2 標準核准通過,可詳見其官方文件。
亦可在 NIST 官網發現 Apple corecrypto Module 確實已通過 FIPS 140–3 CMVP 最新的驗證,已被證實是相當地安全。
後記
其實微軟官網也有建議各種產品、各種程式語言,必須使用哪些經核准的常見亂數產生器:
我們在開發時,若遇到要實作含有亂數的功能,需要安全等級高一點亂數如產生隨機 OTP 或者產生加解密的 key 時,可以多想想這些安全的亂數產生函式,提供給大家自行參考,自行取用,不必重造(不安全的)輪子啦!