低安全性 PRNG
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
OWASP 類別:MASVS-CRYPTO:加密編譯
簡介
虛擬亂數產生器 (PRNG) 是一種演算法,能夠根據稱為「種子」的起始值產生可預測的數序。PRNG 產生的數序具有與真正隨機數序大致相同的屬性,但設定速度更快,設定時的運算成本也較低。
換句話說,PRNG 較有把握提供比低安全性 RNG (例如 java.math.Random
) 還要高的熵發布均勻度,能夠模擬真正的隨機數序。想產生真正的隨機號碼,必須有相關的專業設備,這種產生作業通常超出一般開發範圍。本文並未介紹真正隨機號碼產生作業,而且僅著重於當做標準方法使用的 PRNG。
如果開發人員將一般 PRNG 用於加密編譯,而不是使用經過加密編譯的 PRNG (CSPRNG),就會出現低安全性 PRNG 漏洞。CSPRNG 有更嚴格的規定,且當種子不明時,CSPRNG 必須確保攻擊者僅在區分輸出內容序列和真正的隨機序列方面占有優勢,但這些優勢其實微不足道。
此外,假如可預測的種子 (例如開發人員硬式編碼的種子) 能用於將 PRNG 或 CSPRNG 初始化,由於攻擊者可以猜到種子並據此預測 PRNG 產生的輸出內容,因此也或許能夠猜出最終產生的數序。
影響
如果將未經過加密編譯且安全無虞的 PRNG 用於安全性作業 (例如驗證),攻擊者或許可以猜到隨機產生的數字,進而取得特殊權限資料或功能的存取權。
因應措施
一般
java.security.SecureRandom
建議用於安全性用途。如果 Linux kernel 為 5.17 以上版本,「或者」封鎖執行緒是可接受的做法,請等待熵累積足夠的數量,再產生隨機號碼 (也就是使用 /dev/random
)。如要這麼做,請呼叫 getInstanceStrong()
:
Kotlin
val rand = SecureRandom.getInstanceStrong()
Java
SecureRandom rand = SecureRandom.getInstanceStrong();
但如果 Linux kernel 為 5.17 以下版本,且產生隨機號碼時不允許封鎖執行緒,那麼則可直接呼叫 SecureRandom
建構函式:
Kotlin
import java.security.SecureRandom
object generateRandom {
@JvmStatic
fun main(args: Array<String>) {
// Create instance of SecureRandom class
val rand = SecureRandom()
// Generate random integers in range 0 to 999
val rand_int = rand.nextInt(1000)
// Use rand_int for security & authentication
}
}
Java
import java.security.SecureRandom;
public class generateRandom {
public static void main(String args[])
{
// Create instance of SecureRandom class
SecureRandom rand = new SecureRandom();
// Generate random integers in range 0 to 999
int rand_int = rand.nextInt(1000);
// Use rand_int for security & authentication
}
}
SecureRandom
會從 /dev/urandom
擷取預設種子,並自動在建構或取得物件時使用,因此使用者不需要明確擷取 PRNG 的種子。一般而言,我們不建議使用 SecureRandom,特別是如果這麼做會對種子值進行硬式編碼,且所有對應用程式進行反編譯的人都看得到該種子值。假如開發人員想要產生可重現的虛擬亂數輸出內容,就必須使用更加適當的原始物件,例如 HMAC、HKDF、SHAKE 等等。
java.util.Random
適用於各種用途 (確保安全性或進行驗證除外)。
Kotlin
import java.util.Random
object generateRandom {
@JvmStatic
fun main(args: Array<String>) {
// Create instance of SecureRandom class
val rand = Random()
// Generate random integers in range 0 to 999
val rand_int = rand.nextInt(1000)
}
}
Java
import java.util.Random;
public class generateRandom {
public static void main(String args[])
{
// Create instance of Random class
Random rand = new Random();
// Generate random integers in range 0 to 999
int rand_int = rand.nextInt(1000);
}
}
資源
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2024-01-05 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2024-01-05 (世界標準時間)。"],[],[],null,["# Weak PRNG\n\n\u003cbr /\u003e\n\n**OWASP category:** [MASVS-CRYPTO: Cryptography](https://mas.owasp.org/MASVS/06-MASVS-CRYPTO)\n\nOverview\n--------\n\nA pseudorandom number generator (PRNG) is an algorithm that generates\npredictable number sequences based on a starting value called a *seed* . A\nPRNG-generated number sequence has **approximately** the same properties as a\ntruly random number sequence, but is faster and less computationally expensive\nto create.\n\nIn other words, PRNGs have higher assurances than weak RNGs (e.g.\n`java.math.Random`) in terms of evenness of entropy distribution, which emulate\ntruly random number sequences. Truly random number generation requires\nspecialized equipment and is often outside the scope of normal development. This\ndocument does not cover truly random number generation, and focuses only on\nPRNGs as they are the standard methodology in use.\n\nWeak PRNG vulnerabilities occur when developers use a regular PRNG for\ncryptographic purposes, instead of a cryptographically-secure PRNG (CSPRNG).\nCSPRNGs have stricter requirements, and when the seed is unknown, they must give\nan attacker only an insignificant advantage in differentiating an output\nsequence from an actual random sequence.\n\nAttackers may also be able to guess the generated number sequence when\npredictable seeds -- such as those hard coded by the developer -- are used to\ninitialize a PRNG or CSPRNG, as the attacker can guess the seed and thus predict\nthe output generated by the PRNG.\n\nImpact\n------\n\nIf a non-cryptographically secure PRNG is used in a security context like\nauthentication, an attacker may be able to guess the randomly-generated numbers\nand gain access to privileged data or features.\n\nMitigations\n-----------\n\n### General\n\n- Use [`java.security.SecureRandom`](/reference/java/security/SecureRandom) when there are *security implications*\n- Use [`java.util.Random`](/reference/java/util/Random) for any other cases\n- **Never** use [`Math.random`](/reference/java/lang/Math#random())!\n\n### java.security.SecureRandom\n\n**Recommended** for security uses. If the Linux kernel version is 5.17+ *or*\nblocking the thread is acceptable, wait for enough entropy to accumulate before\nyou generate the random numbers (i.e. use `/dev/random`). To do so, call\n`getInstanceStrong()`: \n\n### Kotlin\n\n val rand = SecureRandom.getInstanceStrong()\n\n### Java\n\n SecureRandom rand = SecureRandom.getInstanceStrong();\n\nOtherwise, on Linux kernel versions prior to 5.17 when blocking the thread is\nunacceptable when generating random numbers, then the `SecureRandom` constructor\nshould be called directly: \n\n### Kotlin\n\n import java.security.SecureRandom\n\n object generateRandom {\n @JvmStatic\n fun main(args: Array\u003cString\u003e) {\n // Create instance of SecureRandom class\n val rand = SecureRandom()\n\n // Generate random integers in range 0 to 999\n val rand_int = rand.nextInt(1000)\n\n // Use rand_int for security & authentication\n }\n }\n\n### Java\n\n import java.security.SecureRandom;\n\n public class generateRandom {\n\n public static void main(String args[])\n {\n // Create instance of SecureRandom class\n SecureRandom rand = new SecureRandom();\n\n // Generate random integers in range 0 to 999\n int rand_int = rand.nextInt(1000);\n\n // Use rand_int for security & authentication\n }\n }\n\n`SecureRandom` gets the default seed from `/dev/urandom`, and is automatically\nused when the object is constructed or obtained, so there is no need to\nexplicitly seed the PRNG. In general, any deterministic usage of `SecureRandom`\nis discouraged (especially if this leads to hard coding a seed value, which\nanyone decompiling the app can see). Developers who want to generate\nreproducible pseudorandom output should use more appropriate primitives such as\nHMAC, HKDF, and SHAKE.\n\n### java.util.Random\n\n**Avoid** for security / authentication purposes, acceptable to use for anything\nelse. \n\n### Kotlin\n\n import java.util.Random\n\n object generateRandom {\n @JvmStatic\n fun main(args: Array\u003cString\u003e) {\n // Create instance of SecureRandom class\n val rand = Random()\n\n // Generate random integers in range 0 to 999\n val rand_int = rand.nextInt(1000)\n }\n }\n\n### Java\n\n import java.util.Random;\n\n public class generateRandom {\n\n public static void main(String args[])\n {\n // Create instance of Random class\n Random rand = new Random();\n\n // Generate random integers in range 0 to 999\n int rand_int = rand.nextInt(1000);\n }\n }\n\nResources\n---------\n\n- [java.security.SecureRandom](/reference/java/security/SecureRandom)\n- [java.util.Random](/reference/java/util/Random)\n- [Math.random](/reference/java/lang/Math#random())\n- [Predictable Seed CWE](https://cwe.mitre.org/data/definitions/337.html)\n- [Cryptographically Weak PRNG CWE](https://cwe.mitre.org/data/definitions/338.html)\n- [Java Secure Random](https://www.baeldung.com/java-secure-random)\n- [Java Random versus SecureRandom](https://www.geeksforgeeks.org/random-vs-secure-random-numbers-java/)\n- [How to use SecureRandom](https://tersesystems.com/blog/2015/12/17/the-right-way-to-use-securerandom/)\n- [Python PRNG security guidance](https://rules.sonarsource.com/python/RSPEC-2245)\n- [OWASP Cryptographic Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#secure-random-number-generation)\n- [CVE-2013-6386: Weak PRNG vuln in Drupal](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-6386)\n- [CVE-2006-3419: Weak PRNG vuln in Tor](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3419)\n- [CVE-2008-4102: Predictable Seed in Joomla](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-4102)\n- [Linux Kernel random patch](https://lwn.net/Articles/884875/)"]]