Android 安全随机数生成:SecureRandom 与弱 PRNG 检测实战(OWASP MASTG MASVS-CRYPTO-1)
文档教程网络安全【免费下载链接】mastgThe OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.项目地址https://gitcode.com/gh_mirrors/ow/mastg点击查看免费下载导读密码学安全性高度依赖高质量的伪随机数生成器PRNG密钥、初始化向量IV、nonce、认证令牌、会话标识符与口令等安全敏感数据一旦由可预测的随机源生成整个安全体系便会崩溃。OWASP MASTG 在知识条目 MASTG-KNOW-0013 中系统总结了 Android 平台随机数生成的核心结论java.util.Random等标准类不提供足够随机性必须使用SecureRandom并注意旧版本 Android 的 PRNG 初始化缺陷。本文以该知识条目为主线结合 MASTG 仓库中的静态分析测试MASTG-TEST-0016、新版测试MASTG-TEST-0204、MASTG-TEST-0205、Semgrep 规则mastg-android-random-apis-insufficient-entropy.yml与演示工程 MASTG-DEMO-0007完整讲解弱 PRNG 的成因、SecureRandom 的正确用法、可复现的自动化检测流程以及人工验证要点。为什么java.util.Random不适合安全场景MASTG 知识条目指出标准 Java 类java.util.Random无法提供足够随机性攻击者甚至可能预测下一个将被生成的值并利用该预测冒充其他用户或访问敏感信息。这并非夸大其词而是由其算法本质决定的。线性同余生成器的可预测性MASTG-TEST-0204 的 Overview 对此做了精确补充java.util.Random是线性同余生成器LCG对于任何给定的种子值都会产生可预测的、完全可复现的序列。同一条测试还强调Math.random()本质上只是在一个静态java.util.Random实例上调用nextDouble()因此同样具备可预测性。这意味着一旦攻击者知道所用 PRNG 的类型并观察到若干历史输出就可能写出概念验证代码推算出下一个随机值。MASTG-TEST-0016 引用了对 Java Random 的经典预测攻击Predicting the next Math.random() in Java指出对于非常弱的自定义随机生成器甚至可以通过统计方式观察其模式。若这类随机数被用于生成密码、认证令牌、会话 ID 或加密密钥攻击者即可据此伪造身份或实施会话劫持。何时应当警惕MASTG-TEST-0016 给出了一个实用的判断准则如果某个 PRNG 没有被明确宣传为密码学安全例如java.util.Random它大概率只是统计意义上的 PRNG不应被用于安全敏感上下文。同理若一个 PRNG 的种子已知或可被猜出那么即使算法本身看似复杂其输出序列也是可以预测的——测试中引用了 Ensure that SecureRandom is properly seeded 的原则并给出一个经验参考值128 位种子是产生足够随机数字的良好起点。SecureRandom正确选择与正确用法为什么选择 SecureRandomMASTG 知识条目给出的结论非常直接一般情况下应当使用SecureRandom。它的底层实现由经过审计的密码学算法驱动能够从系统熵源如 Linux 的/dev/urandom获取种子与补充熵输出不可预测的随机值。关于底层 provider知识条目特别说明在 Android 上SecureRandom背后的 PRNG provider 使用来自AndroidOpenSSL即 Conscryptprovider 的SHA1PRNG。这一点需要结合 Android 平台历史来理解Android 7.0API level 24及以上官方建议停止指定安全 provider因为Cryptoprovider 已被弃用其附带的SHA1PRNG也随之废弃见 0x05e-Testing-Cryptography.md 中引用的 Security provider Crypto deprecated in Android NAndroid 8.1API level 27及以上ConscryptAndroidOpenSSL被明确优先于 Bouncy Castle 使用并新增了KeyGenerator:AES、KeyGenerator:HMACSHA256等一系列实现。从 MASTG 的测试与最佳实践看核心建议是不要显式指定 provider直接使用默认实现AndroidOpenSSL / Conscrypt仅在 Android Keystore 系统相关场景才需要指定 provider。只使用无参构造器知识条目给出了一个容易踩坑的关键约束大多数开发者应当通过不带任何参数的无参构造器实例化SecureRandom。其他构造器如显式指定种子SecureRandom(byte[] seed)或指定 provider 的构造器面向高级用途如果使用不当会降低随机性与安全性。MASTG-TEST-0016 的静态分析步骤与之呼应找出所有不是通过默认构造器创建的SecureRandom实例——显式指定种子值可能减少随机性只允许使用无参构造器SecureRandom()它使用系统指定的种子生成 128 字节长的随机数。这里有一个常见的反模式需要警惕出于可复现测试或简化调试的目的手动传入固定种子例如new SecureRandom(byteArrayOf(1,2,3,...))。虽然这能让随机序列确定化但一旦种子可被猜测整个随机体系就不复存在。正确做法是让系统从熵源自行播种。安全与不安全的对比示例MASTG 仓库的演示工程 MASTG-DEMO-0007 提供了一个极其直观的正反对照见 MastgTest.kt// 不安全用于生成认证令牌 val random1 Random().nextDouble() // 不安全Math.random() 本质是 java.util.Random 的 nextDouble() val random2 1 Math.random() // 不安全用 java.util.Random 逐个字符生成密码 val random Random() for (i in 0 until length) { password.append(characters[random.nextInt(characters.length)]) } // 安全SecureRandom 无参构造器 val random4 SecureRandom().nextInt(21)这段代码清晰展示了三种典型的弱随机用法Random()、Math.random()、用Random生成密码与一种正确用法SecureRandom无参构造。其中用Random逐字符拼接密码是最危险的场景之一攻击者只要观察到少量密码样本即可推断内部状态进而预测后续所有随机密码。不只是弱 PRNG非随机源同样危险除了java.util.Random这类弱 PRNG另一类常见漏洞是使用非随机源充当随机值。MASTG-TEST-0205 专门针对此类问题应用依赖当前时间如Date().getTime()或Calendar.MILLISECOND来产生随机值这些值极易被猜测且可复现。典型场景包括用System.currentTimeMillis()生成会话 ID、用时间戳当 nonce 或 IV——攻击者只需知道大致生成时间即可缩小取值范围甚至直接重放。MASTG 仓库为此提供了对应的自动化检测规则 mastg-android-non-random-use.yml其模式匹配覆盖三种非随机源new Date()System.currentTimeMillis()(Calendar $C).get(...)规则的 message 为[MASVS-CRYPTO-1] The application makes use of non-random sources.触发即告警。实战检测用 Semgrep 规则自动化定位弱随机数MASTG 仓库将上述知识沉淀为可直接运行的静态分析规则最核心的一条是 mastg-android-random-apis-insufficient-entropy.ymlmastg-android-random-apis-insufficient-entropy针对 Java 代码告警级别为 WARNING消息为[MASVS-CRYPTO-1] The application makes use of random number generators with insufficient entropy.。其核心匹配模式为pattern-either: - patterns: - pattern-inside: $M(...){ ... } - pattern-either: - pattern: Math.random(...) - pattern: (java.util.Random $X).$Y(...)即在任意方法体内凡是调用Math.random(...)或对java.util.Random实例发起方法调用的位置都会被命中。规则源码可从该文件直接查看其思路源自 mstg-crypto-6 的业界实践。在真实示例上运行规则MASTG-DEMO-0007 演示了如何将规则跑在示例代码上该目录下还有对应的run.sh可供复现。规则在 MastgTest_reversed.java 上报告了 3 处代码发现对应output.txt中的结果❯❱ rules.mastg-android-random-apis-insufficient-entropy [MASVS-CRYPTO-1] The application makes use of random number generators with insufficient entropy. 22┆ double random1 new Random().nextDouble(); 23┆ double random2 1 Math.random(); 27┆ password.append(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .charAt(random.nextInt(...length())));注意示例第 32 行的SecureRandom().nextInt(21)并未被规则命中——这正好印证了SecureRandom 是安全生成器的结论。规则能够自动区分Random/Math.random不安全与SecureRandom安全。评估与人工验证确认随机数是否用于安全上下文自动化规则只能告诉你哪里用了可疑 API真正判定漏洞是否成立还需要确认这些随机值是否进入了安全敏感上下文。两条新版测试都要求按如下标准人工复核使用 MASTG-TECH-0023 反编译定位代码位置随机值是否被用于生成密码、PIN是否被用于生成认证令牌、会话标识符是否被用于生成加密密钥、IV、nonce。具体判据如下MASTG-TEST-0204Insecure Random API Usage测试失败的条件是发现上述不安全 API 生成的随机数被用在安全相关场景如生成密码或认证令牌如果弱随机值仅用于非敏感用途如 UI 动画抖动、游戏随机事件则不构成漏洞MASTG-TEST-0205Non-random Sources Usage测试失败的条件是发现安全敏感值如密码或令牌由非随机源时间戳等生成。以 MASTG-DEMO-0007 的评估为例三处命中的严重程度各不相同第 12 行Random().nextDouble()用于生成认证令牌直接构成安全漏洞第 17 行1 Math.random()位于函数get_random内需要进一步追踪调用方确认随机值去向第 27 行属于密码生成函数安全关键操作必须修复。动态分析补充除了静态分析MASTG-TEST-0016 还建议在加密方法上挂接运行时监控MASTG-TECH-0033来观察输入输出值确定密钥等随机材料的实际流向。对于纯粹检验随机数质量的需求可以采集大量输出样本后用 Burp Sequencer 等工具做统计学分析评估随机性质量。Android 版本适配警惕 4.1–4.3 的 PRNG 缺陷知识条目特别提醒如果应用需要支持Android 4.4API level 19以下的版本必须额外处理 Android 4.1–4.3API level 16–18中PRNG 未能正确初始化的已知缺陷该问题由官方在 2013 年的 Some SecureRandom Thoughts 文章中披露。当时受影响版本中的SecureRandom在某些情况下可能生成可预测的随机序列直接威胁到依赖它的加密操作。结合 0x05e-Testing-Cryptography.md 中的平台演进说明适配策略总结如下Android 版本应对策略4.1–4.3API 16–18存在 PRNG 初始化缺陷需额外修复措施并确保安全 provider 随 Google Play 服务更新4.4API 19及以上缺陷已修复可直接使用无参SecureRandom()7.0API 24及以上Cryptoprovider 及其SHA1PRNG已弃用停止指定 provider使用默认实现8.1API 27及以上ConscryptAndroidOpenSSL为默认首选实现如今绝大多数现代应用的最低支持版本早已高于 API 19但若你的应用仍要兼容老设备请务必阅读官方对该缺陷的修复说明并通过 Google Play 服务机制确保设备上的安全 provider 处于最新状态Updating security provider。修复建议清单综合 MASTG 知识条目与测试要求落地到代码层面应做到统一改用SecureRandom无参构造器val secureRandom SecureRandom()让系统从熵源自播种绝不手动传入固定种子移除所有安全上下文中的java.util.Random与Math.random()包括密码、令牌、会话 ID、密钥、IV、nonce 的生成路径禁止用时间戳等非随机源充当随机值System.currentTimeMillis()、new Date().getTime()、Calendar.MILLISECOND均不可用于安全敏感场景不要显式指定安全 provider使用平台默认的 Conscrypt/AndroidOpenSSL 实现仅在 Android Keystore 场景按需指定引入静态检测规则将 mastg-android-random-apis-insufficient-entropy.yml 与 mastg-android-non-random-use.yml 纳入 CI配合人工复核确认随机值的最终用途关注版本边界若支持 Android 4.4 以下版本补齐对 API 16–18 PRNG 缺陷的处置。延伸阅读知识条目MASTG-KNOW-0013 — Random Number Generation旧版测试MASTG-TEST-0016 — Testing Random Number Generation新版测试MASTG-TEST-0204 — Insecure Random API Usage、MASTG-TEST-0205 — Non-random Sources Usage演示工程MASTG-DEMO-0007含 MastgTest.kt 与 output.txt检测规则mastg-android-random-apis-insufficient-entropy.yml、mastg-android-non-random-use.yml方法论章节0x05e-Testing-Cryptography.md — Random Number Generation赞分享文档教程网络安全【免费下载链接】mastgThe OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.项目地址https://gitcode.com/gh_mirrors/ow/mastg点击查看免费下载相关推荐使用 semgrep 静态扫描 Android 应用中不安全的对称加密算法OWASP MASTG 的 MASVS-CRYPTO-1 实战演示使用 semgrep 静态扫描 Android 应用中不安全的对称加密算法OWASP MASTG 的 MASVS CRYPTO 1 实战演示 本文以 OWAS文档教程网络安全OWASP MASTG 移动应用安全测试实战MASTG-DEMO-0055 检测并审计允许任意主机名的 HostnameVerifier 弱实现OWASP MASTG 移动应用安全测试实战MASTG DEMO 0055 检测并审计允许任意主机名的 HostnameVerifier 弱实现 本文基于 O文档教程网络安全OWASP MASTG 最佳实践iOS 应用如何正确使用安全随机数生成器CSPRNG API 选型与检测指南OWASP MASTG 最佳实践iOS 应用如何正确使用安全随机数生成器CSPRNG API 选型与检测指南 随机数是密钥生成、初始化向量IV、non文档教程网络安全上一篇无审查AI的伦理与责任Qwen3.6-27B-AEON-Ultimate-Uncensored-BF16用户手册下一篇【免费下载】 CityEngine规则文件集合创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考