淺談常見的安全亂數產生函式

Archer Lin
雅砌工坊
Published in
9 min readAug 17, 2022
credit: shutterstock

密碼學上有所謂的「安全偽亂數生成器(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
  2. randomUUID

1. SecureRandom (符合FIPS 140–2)

其實於 Android (JAVA)環境中,最常見的安全亂數產生函式只有一個,就是這個 SecureRandom(),這在 JAVA 官方 APIAndroid 官方 API 都已經註明了他是符合 FIPS 140–2的資安標準,就放心使用吧。

https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html
https://developer.android.com/reference/java/security/SecureRandom

2. randomUUID (符合FIPS 140–2)

嚴格來說 UUID 是用於電腦體系中以辨識資訊的一個128位元識別碼,原本並不是當作產生安全亂數的函式之用,但測試時反組譯別人寫的App常發現,也很常有開發者用這個來產生隨機字串。查了一下 randomUUID() 的原始程式碼,也是採用 SecureRandom() 來實作亂數產生,所以理論上勉強也算是足夠安全了。

https://stackoverflow.com/questions/39786902/uuid-randomuuid-vs-securerandom

iOS常見的安全亂數產生函式

  1. arc4random系列
  2. SecRandomCopyBytes, SecRandomRef 系列
  3. /dev/random, /dev/urandom 系列
  4. Apple corecrypto Module

1. arc4random系列 (符合NIST 800–90A)

arc4random 系列含 arc4random(), arc4random_buf(), arc4random_uniform() 等,深入研究他實作的原始程式碼後,發現是符合 NIST 800–90A 資安標準的。

https://opensource.apple.com/source/Libc/Libc-1158.1.2/gen/FreeBSD/arc4random.c.auto.html

從他們的原始程式碼中可以發現都採用ccdrbg_generate()函式實作,再去查找其實作關鍵函式 ccdrbg_generate() Header 的原始程式碼,找到符合 NIST 800–90A 的佐證。

https://opensource.apple.com/source/xnu/xnu-3789.31.2/EXTERNAL_HEADERS/corecrypto/ccdrbg.h.auto.html
https://opensource.apple.com/source/xnu/xnu-3789.31.2/EXTERNAL_HEADERS/corecrypto/ccdrbg.h.auto.html

2. SecRandomCopyBytes, SecRandomRef 系列 (符合NIST 800–90A)

這其實是目前 Apple 官方最推薦的使用的安全亂數產生函式,也表明了會持續更新它的安全性。於 Apple 官網 API 就開宗明義地宣稱他是密碼學定義上的安全亂數產生函式,官網討論區也有相關描述,是符合 NIST SP800–90A 資安標準的。

https://developer.apple.com/documentation/security/1399291-secrandomcopybytes
https://developer.apple.com/forums/thread/96907

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 的資安標準。

https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp2389.pdf
https://support.apple.com/en-ie/guide/security/seca0c73a75b/web
https://support.apple.com/en-ie/guide/security/seca0c73a75b/web

4. Apple corecrypto Module (符合FIPS 140–2, FIPS 140–3)

這是 Apple 官方開發出的一套嵌入式的硬體加密編譯模組,Apple 官網也說明了 Apple corecrypto Module 於2019年即通過 FIPS 140–2 驗證,其提供的 DRBG 亂數產生方式,是經 FIPS 140–2 標準核准通過,可詳見其官方文件

https://support.apple.com/zh-tw/guide/sccc/sccc2c9de6164/web
https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3431.pdf

亦可在 NIST 官網發現 Apple corecrypto Module 確實已通過 FIPS 140–3 CMVP 最新的驗證,已被證實是相當地安全。

https://csrc.nist.gov/projects/cryptographic-module-validation-program/modules-in-process/modules-in-process-list

後記

其實微軟官網也有建議各種產品、各種程式語言,必須使用哪些經核准的常見亂數產生器:

https://docs.microsoft.com/zh-tw/azure/security/develop/threat-modeling-tool-cryptography

我們在開發時,若遇到要實作含有亂數的功能,需要安全等級高一點亂數如產生隨機 OTP 或者產生加解密的 key 時,可以多想想這些安全的亂數產生函式,提供給大家自行參考,自行取用,不必重造(不安全的)輪子啦!

--

--