OWASP MASTG 实战:Android 自定义证书库与证书固定(Certificate Pinning)测试指南

发布时间:2026/10/9 2:18:21
OWASP MASTG 实战:Android 自定义证书库与证书固定(Certificate Pinning)测试指南
文档教程网络安全【免费下载链接】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点击查看免费下载证书固定Certificate Pinning / Identity Pinning是 Android 应用抵御中间人MITM攻击、将信任范围收窄到特定证书或公钥的关键加固手段。本文以 OWASP MASTGMobile Application Security Testing Guide测试用例 MASTG-TEST-0022Testing Custom Certificate Stores and Certificate Pinning 为核心骨架完整覆盖静态分析Network Security Configuration、TrustManager、网络库与 WebView、Xamarin、Cordova与动态分析代理拦截、objection 绕过验证两条路径并结合仓库内相关知识文档与源码级证据进行纵深展开。读完本文你将能够系统性地识别 Android 应用中的各类证书固定实现、判断其是否有效、定位配置缺陷并用 objection 等工具完成运行时验证。版本说明该测试用例对应 MASVS-NETWORK-2V1 中为 MSTG-NETWORK-4适用级别 L2当前在仓库中已标记为deprecated由 MASTG V2 中的新用例 MASTG-TEST-0242、MASTG-TEST-0243 和 MASTG-TEST-0244 取代。本文会在相应小节指出新旧用例的承接关系帮助读者平滑迁移到 V2 测试体系。为什么需要证书固定从信任所有 CA到只信任指定身份在深入测试方法之前先理解证书固定的本质。MASTG 网络通信章节Document/0x04f-Testing-Network-Communication.md指出操作系统默认信任所有系统内置 CA而设备用户还可以自行添加 CA。对金融、健康类等高风险应用而言即使系统 CA 被攻破是小概率事件也必须纳入威胁模型——证书固定就是把信任从所有被信任 CA 签发的证书收窄为某一个特定身份X.509 证书、公钥或其哈希只有身份匹配时才建立连接从而减少攻击面。MASTG 关于固定Pinning的几个关键结论可直接作为测试评估依据固定推荐在开发阶段预加载进行固定对象首选证书公钥 SPKIsubjectPublicKeyInfo的哈希必须包含备用固定backup pin一旦需要更换密钥或 CA若没有备用 pin应用将无法恢复连接只能强制推送客户端更新对 MAS-L2 应用而言固定是必须实现的要求但对未实现固定的应用不应简单判定为漏洞需结合威胁模型评估固定能防御CA 被攻破或设备上被安装了恶意 CA但无法防御控制了设备的攻击者——攻击者可以轻易禁用固定逻辑因此固定不能替代服务端安全防护移动端固定与 Web 的 HTTP Public Key PinningHPKP不同HPKP 在网站侧已不推荐使用而移动应用可通过应用商店这一带外渠道更新不存在锁死用户的问题。静态分析定位应用中的证书固定实现静态分析的目标是确认应用是否以及以何种方式实现了证书固定。Android 上的实现途径多种多样MASTG 知识库 MASTG-KNOW-0015Certificate Pinning 将其归纳为以下几类本测试的静态分析部分基本按此脉络展开实现途径适用场景关键检测点Network Security ConfigurationNSCAPI 24 的推荐方式声明式配置res/xml中的pin-set与expiration自定义 TrustManagerjavax.net.ssl需要更细粒度控制时TrustManagerFactory、KeyStoreBKS、SSLContext.init第三方网络库如 OkHttp使用网络库的应用CertificatePinner.Builder的add()调用WebView应用内嵌网页场景WebViewClient的onLoadResource、shouldInterceptRequest跨平台框架Xamarin、Cordova 等混合/跨平台应用ServicePointManager、Cordova 插件调用原生代码.so高对抗场景编译进 native 库的证书或哈希校验重要从源码结构推断的内容例如某些库底层基于自定义 TrustManager仅作辅助判断测试结论必须以可观察证据为准。1. Network Security ConfigurationNSC检查pin-set与过期时间NSC 是 Android 7.0API level 24起引入的机制允许应用以 XML 声明式配置网络安全策略其核心能力包括明文流量控制、自定义信任锚、证书固定、仅调试用覆盖MASTG-KNOW-0014Android Network Security Configuration。检查步骤如下反编译应用参考 MASTG-TECH-0013取出AndroidManifest.xml查找application标签上的android:networkSecurityConfig属性定位配置文件通常位于res/xml/network_security_config.xml检查配置中是否存在pin-set元素记录其覆盖的domain检查expiration日期如果 pin 已过期Android 将不再对该域名强制执行证书固定连接的认证会回退到配置的信任锚trust anchors——此时应用可能接受它本不该信任的 CA 签发的证书。这一检查点正是 V2 新用例 MASTG-TEST-0243Expired Certificate Pins in the Network Security Configuration 的核心评估内容只要面向相关一方first-party域名的 pin 过期时间在过去测试即判定失败。一个完整的 NSC 固定配置示例摘自 MASTG-KNOW-0015包含备用 pin?xml version1.0 encodingutf-8? network-security-config domain-config !-- 对 owasp.org 及其子域名启用证书固定 -- domain includeSubdomainstrueowasp.org/domain pin-set expiration2028-12-31 !-- 服务器证书的中间 CA 公钥X.509 证书的 SubjectPublicKeyInfo哈希 -- pin digestSHA-256YLh1dUR9y6Kja30rRAn7JKnbQG/uEtLMkBgFF2Fuihg/pin !-- 服务器证书的根 CA 公钥哈希作为备用 pin -- pin digestSHA-256Vjs8r4z80wjNcr1YKepWQboSIRi63WsWXhIMNeWys/pin /pin-set /domain-config /network-security-config理解 NSC 固定生效的底层流程有助于判断配置是否有效依据 MASTG-KNOW-0015当应用连接远程端点时系统会取出传入的证书、提取其公钥、对公钥计算摘要并将摘要与本地 pin 集合比对只要至少一个 pin 的摘要匹配证书链即视为有效连接继续建立。此外还应注意适用范围NSC 只作用于 Android 框架托管的网络流量基于HttpsURLConnection的连接以及 WebView 请求除非使用了自定义 TrustManager原生代码发起的连接不受 NSC 约束需要其他机制优先级base-config作用于应用所有连接domain-config对指定域名覆盖base-configMASTG-KNOW-0014。Android 9API 28及以上目标应用的默认配置为base-config cleartextTrafficPermittedfalse且仅信任系统 CA验证 NSC 是否被加载如果配置存在系统日志中应出现D/NetworkSecurityConfig: Using Network Security Config from resource network_security_config。系统日志提示当证书固定校验失败时系统日志logcat参考 MASTG-TECH-0009会记录以下事件这是动态测试中最直观的判定信号I/X509Util: Failed to validate the certificate chain, error: Pin verification failedV2 新用例 MASTG-TEST-0242Missing Certificate Pinning in Network Security Configuration 专门评估NSC 中是否对相关一方域名配置了固定若应用连接了相关一方域名但未设置networkSecurityConfig或已设置却未对该域名启用固定测试即失败但不应因为无关的第三方域名未固定而报错。若同一域名存在其他固定实现如自定义 TrustManager 或第三方库应视为未由 NSC 覆盖而非确认缺失固定。2. TrustManager自定义证书库的经典实现在 NSC 出现之前Android 上实现证书固定的推荐方式是基于javax.net.ssl编写自定义TrustManager。虽然 NSC 已是推荐做法现代应用出于灵活性仍会使用该方案MASTG-KNOW-0015因此测试者必须掌握其检查方法。实现证书固定主要包含三步获取目标主机们的证书确保证书为.bksBouncyCastle格式将该证书固定到默认 Apache Httpclient 的实例上。分析时应确认 HTTP 客户端是否正确加载了 KeyStore。正确的加载方式如下JAVA 代码完整保留自原测试用例InputStream in resources.openRawResource(certificateRawResource); keyStore KeyStore.getInstance(BKS); keyStore.load(resourceStream, password);KeyStore 加载完成后即可使用只信任该 KeyStore 中 CA 的 TrustManagerString tmfAlgorithm TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); // Create an SSLContext that uses the TrustManager // SSLContext context SSLContext.getInstance(TLS); sslContext.init(null, tmf.getTrustManagers(), null);分析要点应用的具体实现可能各不相同——可能只固定证书的公钥、固定整个证书或固定整条证书链。测试者需结合代码逐一定位固定粒度。与此同时自定义 TrustManager 属于底层方案极易出错MASTG-KNOW-0015静态分析时应警惕以下反模式SSLSocket不会自动校验主机名必须配合安全的HostnameVerifier实现并显式检查verify()的返回值绝不使用信任一切trust-all的 TrustManager——它会静默接受所有证书攻击者几乎不费吹灰之力即可解密和篡改用户数据。这类实现正是姊妹测试 MASTG-TEST-0021Testing Endpoint Identify Verification 重点排查的对象如重写checkClientTrusted、checkServerTrusted、getAcceptedIssuers为空实现的代码片段。3. 网络库与 WebViewOkHttp 与 WebViewClientOkHttp 等第三方网络库通常自带固定能力。例如 OkHttp 的CertificatePinner可通过链式 Builder 配置JAVA 代码完整保留自原测试用例OkHttpClient client new OkHttpClient.Builder() .certificatePinner(new CertificatePinner.Builder() .add(example.com, sha256/UwQAapahrjCOjYI3oLUx5AQxPBR02Jz6/E2pt0IeLXA) .build()) .build();注意add()的第一个参数是域名第二个参数是 SPKI 公钥的 SHA-256 摘要sha256/base64格式。从实现原理看OkHttp 的固定底层同样借助自定义 TrustManager 强制校验规则MASTG-KNOW-0015。WebView 场景使用 WebView 组件的应用可能通过WebViewClient的事件处理器在目标资源加载前对每次请求执行某种证书固定。以下是典型的验证实现JAVA 代码完整保留自原测试用例WebView myWebView (WebView) findViewById(R.id.webview); myWebView.setWebViewClient(new WebViewClient(){ private String expectedIssuerDN CNLets Encrypt Authority X3,OLets Encrypt,CUS;; Override public void onLoadResource(WebView view, String url) { //From Android API documentation about WebView.getCertificate(): //Gets the SSL certificate for the main top-level page //or null if there is no certificate (the site is not secure). // //Available information on SslCertificate class are Issuer DN, Subject DN and validity date helpers SslCertificate serverCert view.getCertificate(); if(serverCert ! null){ //apply either certificate or public key pinning comparison here //Throw exception to cancel resource loading... } } } });更推荐的替代方案配置带固定规则的 OkHttpClient让其作为代理并覆写WebViewClient的shouldInterceptRequest来承载请求从而复用 OkHttp 的固定能力。另外从 Android 平台行为看NSC 的固定规则会自动作用于同应用内 WebView 加载的资源因此大多数 WebView 场景直接用 NSC 即可MASTG-KNOW-0015。4. Xamarin 应用旧版已停止支持Xamarin 自 2024 年 5 月 1 日起已停止支持End of Support不再接收安全补丁与更新新项目应改用 .NET MAUI。但存量 Xamarin 应用仍可能出现其典型固定实现方式是使用System.Net.ServicePointManager。通常应用会创建一个校验证书的函数并将返回值交给ServerCertificateValidationCallback方法C# 代码完整保留自原测试用例[Activity(Label XamarinPinning, MainLauncher true)] public class MainActivity : Activity { // SupportedPublicKey - Hexadecimal value of the public key. // Use GetPublicKeyString() method to determine the public key of the certificate we want to pin. Uncomment the debug code in the ValidateServerCertificate function a first time to determine the value to pin. private const string SupportedPublicKey 3082010A02820101009CD30CF05AE52E47B7725D3783B...; // Shortened for readability private static bool ValidateServerCertificate( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors ) { //Log.Debug(Xamarin Pinning,chain.ChainElements[X].Certificate.GetPublicKeyString()); //return true; return SupportedPublicKey chain.ChainElements[1].Certificate.GetPublicKeyString(); } protected override void OnCreate(Bundle savedInstanceState) { System.Net.ServicePointManager.ServerCertificateValidationCallback ValidateServerCertificate; base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.Main); TesteAsync(https://security.claudio.pt); }该示例固定的是证书链中的中间 CAHTTP 响应输出可在系统日志中查看。仓库中提供了对应的样例 APKSamples/Android/02_CertificatePinning/certificatePinningXamarin.apk目录说明见 Samples/Android/02_CertificatePinning/readme.md。分析方法解压 APK 后用 .NET 反编译器如 dotPeek、ILSpy 或 dnSpy反编译Assemblies文件夹内的程序集 DLL确认ServicePointManager的使用情况。这里的关键取证点是ValidateServerCertificate是否对固定值做了严格的字符串比较以及是否存在注释掉的return true;调试捷径。5. Cordova 应用混合应用的插件方案基于 Cordova 的混合应用原生不支持证书固定通常依赖插件实现最常用的是 PhoneGap SSL Certificate Checker 插件。插件通过check方法校验指纹由回调函数决定后续流程JavaScript 代码完整保留自原测试用例// Endpoint to verify against certificate pinning. var server https://www.owasp.org; // SHA256 Fingerprint (Can be obtained via openssl s_client -connect hostname:443 | openssl x509 -noout -fingerprint -sha256 var fingerprint D8 EF 3C DF 7E F6 44 BA 04 EC D5 97 14 BB 00 4A 7A F5 26 63 53 87 4E 76 67 77 F0 F4 CC ED 67 B9; window.plugins.sslCertificateChecker.check( successCallback, errorCallback, server, fingerprint); function successCallback(message) { alert(message); // Message is always: CONNECTION_SECURE. // Now do something with the trusted server. } function errorCallback(message) { alert(message); if (message CONNECTION_NOT_SECURE) { // There is likely a MITM attack going on, be careful! } else if (message.indexOf(CONNECTION_FAILED) - 1) { // There was no connection (yet). Internet may be down. Try again (a few times) after a little timeout. } }分析方法解压 APK 后Cordova/PhoneGap 文件位于/assets/www目录plugins文件夹会显示应用使用了哪些插件随后在应用 JavaScript 代码中搜索sslCertificateChecker或check方法的调用确认其是否真正执行了固定校验。动态分析代理拦截与固定绕过验证第一步按端点身份验证用例搭建代理动态分析的第一步是遵循 MASTG-TEST-0021Testing Endpoint Identify Verification 的流程配置拦截代理如 Burp Suite并接管 HTTPS 流量。关键判定逻辑如果流量可以被正常代理解密说明应用没有实现证书固定或实现存在缺陷可继续常规的流量分析如果代理配置正确却始终看不到解密流量很可能应用确实实现了证书固定且安全措施到位。此时应继续验证所有域名都如此吗只对部分域名固定、其他域名可被拦截本身就是一个值得深挖的评估点应用目标版本低于 API 24 时会默认接受用户安装的证书此时即使有固定也容易被绕过需结合静态分析结果判断。V2 将这一动态验证过程正式化为 MASTG-TEST-0244Missing Certificate Pinning in Network Traffic该测试与实现方式无关只要 MITM 拦截能成功即说明相关一方域名要么未固定、要么固定实现错误测试判定失败。与静态取向的 MASTG-TEST-0242 形成互补尤其适用于存在混淆或动态加载代码、难以通过静态分析识别固定实现的场景。测试期间同样建议监控系统日志出现I/X509Util: Failed to validate the certificate chain, error: Pin verification failed即表明应用检测到了 MITM 并拒绝建连。第二步objection 快速冒烟测试作为快速冒烟测试可以尝试用 objectionMASTG-TOOL-0038绕过证书固定方法详见 MASTG-TECH-0012Bypassing Certificate Pinning。在已 root 的设备上安装 frida-server 后执行android sslpinning disable若应用使用的固定相关 API 被 objection 挂钩相关输出会出现在 objection 的会话输出中第三步解读冒烟测试结果重要注意事项解读 objection 的输出时务必保持谨慎依据原测试用例与 MASTG-TECH-0012存在两种易误判的情形API 覆盖可能不完整objection 内置的挂钩清单未必覆盖应用所用的全部固定 API没有输出不意味着没有固定如果没有任何 API 被挂钩并不能推导出应用未实现固定的结论。在以上两种情况下应用或其部分组件可能以 objection 支持的方式之外的自定义方式实现了固定。因此回到本文的静态分析部分针对性地查找固定指示器pin-set、TrustManagerFactory、CertificatePinner、ServicePointManager、Cordova 插件调用等做更深入的验证若静态手段仍无法突破例如固定逻辑被混淆或位于原生代码中可考虑 MASTG-TECH-0012 中的系统性绕过思路静态绕过解包后在 smali 中grep -ri sha256\|sha1 ./smali替换固定哈希或在assets/res中查找并替换.cer/.crt证书文件与.jks/.bks信任库用keytool -importcert ... -storetype BKS注入代理证书后重新打包签名动态绕过识别应用使用的网络库OkHttp3 等用 Frida 挂钩CertificatePinner.Builder.add之类的关键方法并修改参数从而让固定失效。这类绕过更快捷且无需处理完整性校验。一个完整的绕过示例在 MASTG-TECH-0012 中有详细展开含 BKS 信任库的 keytool 命令与 OkHttp 方法签名搜索示例本文不再赘述。从 MASTG V1 到 V2本测试的演进路径本测试用例已标注deprecatedV2 将其拆分为三个更精细、可独立评估的新用例测试者可据此组织更现代、更可复现的测试流程旧用例V2 替代用例侧重MASTG-TEST-0022本用例MASTG-TEST-0242静态NSC 是否对相关一方域名配置固定MASTG-TEST-0243静态NSC 中固定 pin 是否已过期MASTG-TEST-0244动态运行时能否成功拦截相关一方域名的 HTTPS 流量三个新用例共享同一前置条件识别一方域名first-party domains见 prerequisites/identify-first-party-domains.md且都强调只有开发者控制下、支撑应用核心或安全敏感功能的一方域名才应作为评估对象第三方域名不应仅因出现在流量中或可被拦截而触发报错。判定一方域名通常需要二进制之外的信息必要时应与开发者确认。小结测试 Android 应用的自定义证书库与证书固定核心是回答三个问题应用是否实现了固定以何种机制实现固定是否仍有效静态分析阶段沿 NSC、TrustManager、网络库/WebView、Xamarin、Cordova 五条主线逐一排查本用例 MASTG-KNOW-0015 提供了完整路线图动态分析阶段先用 MASTG-TEST-0021 的代理流程做基线再用 objectionMASTG-TOOL-0038冒烟验证并以系统日志中的X509Util事件作为关键佐证。最后切记固定只防御 CA 妥协与恶意 CA不防御控制设备的攻击者同时务必检查备用 pin 与过期时间避免应用在不知不觉中失去固定保护——这正是 MASTG-TEST-0243 所针对的隐蔽风险。赞分享文档教程网络安全【免费下载链接】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点击查看免费下载相关推荐Android 证书固定Certificate Pinning完全指南基于 OWASP MASTG 的实现、测试与绕过Android 证书固定Certificate Pinning完全指南基于 OWASP MASTG 的实现、测试与绕过 本文基于 OWASP Mobile文档教程网络安全绕过 Android 应用证书固定Certificate PinningMASTG 黑盒测试实用指南绕过 Android 应用证书固定Certificate PinningMASTG 黑盒测试实用指南 本指南聚焦 OWASP Mobile Applica文档教程网络安全OWASP MASTGiOS 证书固定Certificate Pinning绕过技术实战OWASP MASTGiOS 证书固定Certificate Pinning绕过技术实战 本篇基于 OWASP MASTGMobile Applicat文档教程网络安全上一篇终极指南如何彻底移除Windows Defender并禁用Windows安全中心下一篇重塑Windows安全防护深度解析Defender Remover的实战应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考