
文档教程网络安全【免费下载链接】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点击查看免费下载导读本指南基于 OWASP Mobile Application Security Testing Guide (MASTG) 中 Document/0x05e-Testing-Cryptography.md 一章系统讲解 Android 平台密码学 API 的测试方法。Android 密码学体系建立在 Java Cryptography Architecture (JCA) 之上涉及 Security Provider、Android KeyStore/KeyChain 密钥生命周期管理、密钥生成参数规范KeyGenParameterSpec与安全随机数生成等核心环节。读完本文你将掌握如何在 APK 源码中定位密码学 API 的使用、如何评估密钥配置是否符合当前最佳实践、如何识别各 Android 版本API 24/27/28/29带来的密码学行为变化以及如何基于仓库中的知识条目 knowledge/android/MASVS-CRYPTO 与测试用例 tests/android/MASVS-CRYPTO 开展可落地的静态与动态测试。Android 密码学体系概述Android 的密码学 API 基于 JCA 设计其核心思想是将接口与实现分离应用开发者面向统一的接口编程而底层可由多个 Security Provider 提供不同的算法实现。绝大多数 JCA 接口与类定义在java.security.*与javax.crypto.*包中此外还有 Android 特有的android.security.*与android.security.keystore.*包。识别 Android 密码学系统时可重点关注以下知识条目MASTG-KNOW-0011Security Providerknowledge/android/MASVS-CRYPTO/MASTG-KNOW-0011.mdMASTG-KNOW-0012Key Generationknowledge/android/MASVS-CRYPTO/MASTG-KNOW-0012.mdMASTG-KNOW-0013Random Number Generationknowledge/android/MASVS-CRYPTO/MASTG-KNOW-0013.mdKeyStore 与 KeyChain 为密钥的存储和使用提供 APIKeyChain 底层同样使用 KeyStore 系统二者可管理密码学密钥的完整生命周期通常划分为五个阶段生成密钥generating a key使用密钥using a key存储密钥storing a key归档密钥archiving a key删除密钥deleting a key存储阶段的具体分析见 Document/0x05d-Testing-Data-Storage.mdAndroid 数据存储测试一章。这些阶段由 Keystore/KeyChain 系统管理但系统实际行为取决于应用开发者如何实现。因此在分析过程中应聚焦开发者实际使用的函数识别并验证以下环节MASTG-KNOW-0012密钥生成MASTG-KNOW-0013随机数生成密钥轮换Key rotation各 Android 版本的密码学行为变化面向现代 API 级别的应用经历了以下关键变更测试时应据此校准预期Android 7.0API level 24及以上官方建议停止显式指定 Security Provider始终使用已打补丁的 MASTG-KNOW-0011。CryptoProvider 的支持被移除并弃用其用于安全随机数的SHA1PRNG同样被弃用。Android 8.1API level 27及以上优先使用 Conscrypt即AndroidOpenSSL而非 Bouncy CastleConscrypt 新增了AlgorithmParameters:GCM、KeyGenerator:AES、KeyGenerator:DESEDE、KeyGenerator:HMACMD5、KeyGenerator:HMACSHA1、KeyGenerator:HMACSHA224、KeyGenerator:HMACSHA256、KeyGenerator:HMACSHA384、KeyGenerator:HMACSHA512、SecretKeyFactory:DESEDE、Signature:NONEWITHECDSA等实现。GCM 模式下不应再使用IvParameterSpec.class应改用GCMParameterSpec.class。Socket 实现由OpenSSLSocketImpl变更为ConscryptFileDescriptorSocket与ConscryptEngineSocket。参数为 null 的SSLSession会抛出NullPointerException。生成密钥的输入字节数组必须足够大否则抛出InvalidKeySpecException。Socket 读取被中断时抛出SocketException。Android 9API level 28及以上若仍通过getInstance显式指定 Security Providertarget 低于 28 时收到警告target 28 及以上时直接报错。CryptoProvider 已被移除调用会抛出NoSuchProviderException。Android 10API level 29开发者文档列出了全部网络安全的行为变更。总体推荐清单审查应用时应对照以下推荐项遵循 Document/0x04g-Testing-Cryptography.md 一章中的移动应用密码学最佳实践。确保 Security Provider 保持最新参考官方 Updating security provider 指南。停止显式指定 Security Provider使用默认实现AndroidOpenSSL / Conscrypt。停止使用已弃用的CryptoProvider 及其SHA1PRNG。仅为 Android Keystore 系统指定 Security Provider。停止使用无 IV 的基于口令的加密Password-based encryptionCipher。使用KeyGenParameterSpec取代KeyPairGeneratorSpec。Security Provider清单、更新与兼容策略为什么 Security Provider 是测试重点Android 通过java.security.Provider类依赖 Security Provider 来实现 Java 安全服务与基于 SSL/TLS 的连接。这些 Provider 对保障网络通信安全及依赖密码学的其他功能至关重要但随设备内置的 Provider如 OpenSSL版本因 Android 版本和 OEM 定制构建而异往往带有缺陷或已知漏洞。应用不仅要选择正确的算法和良好的配置某些情况下还要关注旧版 Provider 实现的健壮性。自 2016 年 7 月 11 日起Google 已拒绝包括新应用与更新使用含漏洞 OpenSSL 版本的 Play Store 提交因此开发者必须确保应用安装合适的 Security Provider。列出可用 Security Provider使用如下代码枚举当前环境中的所有 ProviderStringBuilder builder new StringBuilder(); for (Provider provider : Security.getProviders()) { builder.append(provider: ) .append(provider.getName()) .append( ) .append(provider.getVersion()) .append(() .append(provider.getInfo()) .append()\n); } String providers builder.toString(); //now display the string on the screen or in the logs for debugging.在带有 Google Play APIs 的模拟器中运行 Android 9API level 28时输出如下provider: AndroidNSSP 1.0(Android Network Security Policy Provider) provider: AndroidOpenSSL 1.0(Androids OpenSSL-backed security provider) provider: CertPathProvider 1.0(Provider of CertPathBuilder and CertPathVerifier) provider: AndroidKeyStoreBCWorkaround 1.0(Android KeyStore security provider to work around Bouncy Castle) provider: BC 1.57(BouncyCastle Security Provider v1.57) provider: HarmonyJSSE 1.0(Harmony JSSE Provider) provider: AndroidKeyStore 1.0(Android KeyStore security provider)更新 Security Provider组件保持最新并已打补丁是安全的基本原则Security Provider 也不例外。应用应检查所使用的 Provider 是否过时若过时则进行更新参见官方 Updating security provider。兼容旧版 Android 的方案对于仅支持低于 Android 7.0API level 24版本的应用捆绑最新库可能是唯一选项。此时Conscrypt是较好的选择它能在不同 API level 间保持密码学行为一致且比体积更重的 Bouncy Castle 更轻量。通过 Gradle 引入 Conscryptdependencies { implementation org.conscrypt:conscrypt-android:last_version }然后注册 ProviderSecurity.addProvider(Conscrypt.newProvider())密钥生成KeyGenParameterSpec 与 AndroidKeyStore用 KeyGenParameterSpec 约束密钥用途Android 6.0API level 23引入了KeyGenParameterSpec类用于精确指定密钥的生成方式与可用场景。例如String keyAlias MySecretKey; KeyGenParameterSpec keyGenParameterSpec new KeyGenParameterSpec.Builder(keyAlias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_CBC) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) .setRandomizedEncryptionRequired(true) .build(); KeyGenerator keyGenerator KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, AndroidKeyStore); keyGenerator.init(keyGenParameterSpec); SecretKey secretKey keyGenerator.generateKey();该KeyGenParameterSpec表明密钥仅可用于加解密不能用于签名、验签等其他用途同时指定了块模式CBC、填充方式PKCS #7并显式要求随机化加密这也是默认值。随后在KeyGenerator.getInstance中传入AndroidKeyStore作为 Provider 名称确保密钥存入 Android KeyStore。若试图违反上述规范使用密钥将抛出安全异常。GCM 是提供认证加密的 AES 模式将加密与数据认证集成为单一过程无需如 CBC 那样额外依赖 HMAC且不要求填充简化了实现并降低漏洞面详见 MASTG-KNOW-0012。使用密钥加密与解密使用上述密钥加密注意 IV 必须保存String AES_MODE KeyProperties.KEY_ALGORITHM_AES / KeyProperties.BLOCK_MODE_CBC / KeyProperties.ENCRYPTION_PADDING_PKCS7; KeyStore AndroidKeyStore AndroidKeyStore.getInstance(AndroidKeyStore); // byte[] input Key key AndroidKeyStore.getKey(keyAlias, null); Cipher cipher Cipher.getInstance(AES_MODE); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] encryptedBytes cipher.doFinal(input); byte[] iv cipher.getIV(); // save both the IV and the encryptedBytes解密input为密文iv为加密阶段保存的初始向量// byte[] input // byte[] iv Key key AndroidKeyStore.getKey(AES_KEY_ALIAS, null); Cipher cipher Cipher.getInstance(AES_MODE); IvParameterSpec params new IvParameterSpec(iv); cipher.init(Cipher.DECRYPT_MODE, key, params); byte[] result cipher.doFinal(input);由于 IV 每次随机生成必须与密文encryptedBytes一并保存否则后续无法解密。旧版API 23 之前的 RSA 密钥对生成Android 6.0 之前不支持 AES 密钥生成许多实现转而使用 RSA 生成公私钥对KeyPairGeneratorSpec或使用SecureRandom生成 AES 密钥。示例Date startDate Calendar.getInstance().getTime(); Calendar endCalendar Calendar.getInstance(); endCalendar.add(Calendar.YEAR, 1); Date endDate endCalendar.getTime(); KeyPairGeneratorSpec keyPairGeneratorSpec new KeyPairGeneratorSpec.Builder(context) .setAlias(RSA_KEY_ALIAS) .setKeySize(4096) .setSubject(new X500Principal(CN RSA_KEY_ALIAS)) .setSerialNumber(BigInteger.ONE) .setStartDate(startDate) .setEndDate(endDate) .build(); KeyPairGenerator keyPairGenerator KeyPairGenerator.getInstance(RSA, AndroidKeyStore); keyPairGenerator.initialize(keyPairGeneratorSpec); KeyPair keyPair keyPairGenerator.generateKeyPair();该示例生成 4096 位模数长度RSA 密钥对椭圆曲线EC密钥也可类似生成但截至 Android 11API level 30AndroidKeyStore 不支持使用 EC 密钥加解密仅可用于签名。基于口令的密钥派生PBKDF2对称密钥可由口令经 Password Based Key Derivation Function version 2PBKDF2派生参数应按 Document/0x04g-Testing-Cryptography.md 中不正确的密钥派生函数一节调整public static SecretKey generateStrongAESKey(char[] password, int keyLength) { //Initialize objects and variables for later use int iterationCount 10000; int saltLength keyLength / 8; SecureRandom random new SecureRandom(); //Generate the salt byte[] salt new byte[saltLength]; random.nextBytes(salt); KeySpec keySpec new PBEKeySpec(password.toCharArray(), salt, iterationCount, keyLength); SecretKeyFactory keyFactory SecretKeyFactory.getInstance(PBKDF2WithHmacSHA1); byte[] keyBytes keyFactory.generateSecret(keySpec).getEncoded(); return new SecretKeySpec(keyBytes, AES); }该方法接收口令字符数组与所需密钥长度如 128 或 256 位 AES定义 10,000 轮迭代——增加迭代次数可显著提升对口令暴力破解的难度但也会消耗更多计算资源。盐长度设为密钥长度除以 8位转字节并使用SecureRandom随机生成。盐必须保持恒定以保证同一口令每次都派生相同的密钥可将盐私有存储于SharedPreferences并建议将其排除在 Android 备份机制之外针对高风险数据同步场景。若将 root 设备或被篡改重打包的应用视为数据威胁更好的做法是用置于AndroidKeyStore中的密钥对盐加密。PBE 密钥派生在 Android 8.0API level 26之前推荐PBKDF2WithHmacSHA1更高 API level 推荐PBKDF2withHmacSHA256哈希值更长。关于 NDK 的误区广泛存在用 NDK 隐藏密码学操作与硬编码密钥的错误观念但该机制并不可靠——攻击者仍可用工具识别所用机制并从内存中 dump 密钥随后用 radare2 分析控制流、用 Frida 提取密钥可参见 MASTG-TOOL-0036以及 MASTG-TECH-0018、MASTG-TECH-0044。且自 Android 7.0API level 24起不允许使用私有 API必须调用公共 API进一步削弱了这种隐藏方式的有效性。随机数生成SecureRandom 的正确使用密码学要求安全的伪随机数生成PRNG。标准 Java 类java.util.Random的随机性不足攻击者可能预测下一个生成值进而冒充其他用户或访问敏感信息。一般应使用SecureRandom。需要注意的历史缺陷若应用支持 Android 4.4API level 19以下的版本则需额外处理 Android 4.1–4.3API level 16–18中 PRNG 初始化失败 的 bug。大多数开发者应通过无参默认构造函数实例化SecureRandom其他构造函数面向高级用法使用不当会降低随机性与安全性。SecureRandom底层 PRNG 使用来自AndroidOpenSSLConscryptProvider 的SHA1PRNG。更多细节参见 Android 官方文档以及 MASTG-KNOW-0013。在源码中定位密码学 API静态分析搜索 JCA 相关类与异常静态分析是评估密码学配置的第一站。以密钥用途测试MASTG-TEST-0015为例应在代码中识别所有密码学使用实例重点搜索类Cipher、Mac、MessageDigest、Signature接口Key、PrivateKey、PublicKey、SecretKey函数getInstance、generateKey异常KeyStoreException、CertificateException、NoSuchAlgorithmException导入包java.security.*、javax.crypto.*、android.security.*、android.security.keystore.*对每个实例确定其用途与类型加密/解密数据机密性、签名/验证数据完整性、部分场景的问责性、维护如密钥导入 KeyStore 期间的保护。同时识别使用这些密码学实例的业务逻辑。验证时应检查所有密钥是否按创建时定义的目的使用对 KeyStore 密钥即KeyProperties非对称密钥是否私钥仅用于签名、公钥仅用于加密对称密钥是否被用于多种用途不同上下文应重新生成新密钥密码学使用是否符合业务目的。定位硬编码密钥的典型流程测试用例 MASTG-TEST-0013 给出了定位硬编码对称密钥的完整流程先反编译/反汇编MASTG-TECH-0017例如使用 MASTG-TOOL-0018 jadx-gui再递归搜索SecretKeySpec的用法grep -r SecretKeySpec返回所有使用SecretKeySpec的类后追踪传递密钥材料的变量。下图为对某生产应用执行该评估的结果可清楚定位到硬编码于静态字节数组Encrypt.keyBytes中的静态加密密钥图中Encrypt工具类以 AES 加解密字符串其private static byte[] keyBytes在静态代码块中直接赋入完整密钥数值{7, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 9, 20, 21, 15, 1, 10, 11, 12, 13, 14, ...}未做混淆或保护encrypt/decrypt方法均将该数组实例化为SecretKeySpec后执行 AES 操作——这正是逆向时最易定位和提取的密钥类型。对每个实例还需验证对称密钥是否不属于应用资源、无法从已知值推导、未硬编码在代码中对每个硬编码对称密钥确认其未在安全敏感场景中作为唯一加密手段。相关自动化测试见 tests-beta/android/MASVS-CRYPTO/MASTG-TEST-0212.md该用例要求先反逆向MASTG-TECH-0013再用相关 API 搜索MASTG-TECH-0014若在安全敏感上下文发现硬编码密钥则判定失败对应 MASWE-0003。动态分析运行时观测密钥材料动态分析阶段可使用 MASTG-TECH-0033 对密码学方法进行 hook获取其输入/输出值如实际使用的密钥同时监控密码学操作期间的文件系统访问评估密钥材料写入/读取的位置例如使用 MASTG-TOOL-0037 的 API monitor 功能。从知识条目到测试用例MASVS-CRYPTO 测试矩阵仓库将测试用例组织为知识条目knowledge/→ 测试用例tests/→ 测试脚本/演示demos/的链条。以本文涉及的 MASVS-CRYPTO 为例知识条目MASTG-KNOW-0011Security Provider、MASTG-KNOW-0012Key Generation、MASTG-KNOW-0013Random Number Generation位于 knowledge/android/MASVS-CRYPTO稳定版测试对称密码学测试MASTG-TEST-0013对应 MSTG-CRYPTO-1与密钥用途测试MASTG-TEST-0015对应 MSTG-CRYPTO-5 / MASVS-CRYPTO-2等位于 tests/android/MASVS-CRYPTO测试版beta用例如 MASTG-TEST-0212硬编码密钥、MASTG-TEST-0307密钥用途等位于 tests-beta/android/MASVS-CRYPTO。MASVS-CRYPTO 对应的通用密码学最佳实践算法选型、密钥长度、配置问题清单等详见 Document/0x04g-Testing-Cryptography.md其中明确将 DES、3DES、RC2、RC4、BLOWFISH、MD4、MD5、SHA1 列为已知弱点算法并推荐 AES-GCM-256 / ChaCha20-Poly1305机密性、SHA-256/384/512、BLAKE3、SHA-3 族完整性、RSA3072 位以上/ ECDSANIST P-384/ EdDSAEdwards448签名等现代算法。测试清单速查应用审查时可对照以下检查项是否仍显式指定 Security Provider应改为默认实现是否仍使用CryptoProvider 或SHA1PRNG均已弃用/移除GCM 模式是否错误使用IvParameterSpec应使用GCMParameterSpec密钥是否通过KeyGenParameterSpec限定用途且仅用于既定目的对称密钥是否硬编码在源码、资源或可从已知值推导是否使用无 IV 的基于口令的加密 Cipher随机数是否一律使用SecureRandom无参构造密钥是否托管于 Android KeyStore生命周期生成/使用/存储/归档/删除是否可管理是否针对 API level 24/27/28/29 的行为差异校准了测试预期总结Android 密码学测试的本质是在 JCA 的接口-实现分离架构下围绕 Security Provider、KeyStore 密钥生命周期与随机数生成三大支柱核对配置是否跟随各 API 级别的演进弃用Crypto/SHA1PRNG、默认 Conscrypt、GCM 使用GCMParameterSpec并验证密钥是否按KeyGenParameterSpec限定的用途使用、是否被硬编码或不当存储。结合仓库中 knowledge/android/MASVS-CRYPTO 的知识条目与 tests/android/MASVS-CRYPTO 的测试用例可将这套方法论落地为可重复的静态搜索与动态 hook 流程从而系统性地发现 Android 应用中的密码学弱点。赞分享文档教程网络安全【免费下载链接】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点击查看免费下载相关推荐OWASP MASTG 实战用 semgrep 检测 Android 加密 API 中显式指定的 Security ProviderMASTG-DEMO-0075OWASP MASTG 实战用 semgrep 检测 Android 加密 API 中显式指定的 Security ProviderMASTG DEMO 0文档教程网络安全OWASP MASTG 最佳实践 MASTG-BEST-0037在生物特征录入变化时使 Android Keystore 密钥失效OWASP MASTG 最佳实践 MASTG BEST 0037在生物特征录入变化时使 Android Keystore 密钥失效 导读 本文讲解 OWAS文档教程网络安全Android Gradle DSL性能优化指南加速构建过程的7个秘诀Android Gradle DSL性能优化指南加速构建过程的7个秘诀 Android Gradle DSLDomain Specific Language创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考