• Stars
    star
    417
  • Rank 101,340 (Top 3 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created about 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

App综合防抓包实践,关闭代理,设置配置文件;设置单向认证或双向认证;对数据加密和解密;sign签名参数;防止xposed,root,va挂载等操作。 比较通用全面的防抓包技术方案!

目录介绍

  • 01.整体概述介绍
    • 1.1 项目背景
    • 1.2 思考问题
    • 1.3 设计目标
    • 1.4 收益分析
  • 02.市面抓包的分析
    • 2.1 Https三要素
    • 2.2 抓包核心原理
    • 2.3 搞定CA证书
    • 2.4 突破CA证书校验
    • 2.5 如何搞定加解密
    • 2.6 Charles原理
    • 2.7 抓包原理图
    • 2.8 抓包核心流程
  • 03.防止抓包思路
    • 3.1 先看如何抓包
    • 3.2 设置配置文件
    • 3.3 数据加密处理
    • 3.4 避免黑科技抓包
  • 04.防抓包实践开发
    • 4.1 App安全配置
    • 4.2 关闭代理
    • 4.3 证书校验
    • 4.4 双向认证
    • 4.5 防止挂载抓包
    • 4.6 数据加解密
    • 4.7 证书锁定
    • 4.8 Sign签名
    • 4.9 其他的方式
  • 05.架构设计说明
    • 5.1 整体架构设计
    • 5.2 关键流程图
    • 5.3 稳定性设计
    • 5.4 降级设计
    • 5.5 异常设计说明
  • 06.防抓包功能自测
    • 6.1 网络请求测试
    • 6.2 抓包测试
    • 6.3 黑科技挂载测试
    • 6.4 逆向破解测试

01.整体概述介绍

1.1 项目背景

  • 通讯安全是App安全检测过程中非常重要的一项
    • 针对该项的主要检测手段就是使用中间人代理机制对网络传输数据进行抓包、拦截和篡改,以检验App在核心链路上是否有安全漏洞。
  • 保证数据安全
    • 通过charles等工具可以对app的网络请求进行抓包,这样这些信息就会被清除的提取出来,会被不法分子进行利用。
  • 不想被竞争对手逆向抓包
    • 不想自身App的数据被别人轻而易举地抓包获取到,从而进行类似业务或数据分析、爬虫或网络攻击等破坏性行为。

1.2 思考问题

  • 开发项目的时候,都需要抓包,很多情况下即使是Https也能正常抓包正常。那么问题来了:
    • 抓包的原理是?任何Https的 app 都能抓的到吗?如果不能,哪些情况下可以抓取,哪些情况下抓取不到?
  • 什么叫做中间人攻击?
    • 使用HTTPS协议进行通信时,客户端需要对服务器身份进行完整性校验,以确认服务器是真实合法的目标服务器。
    • 如果没有校验,客户端可能与仿冒的服务器建立通信链接,即“中间人攻击”。

1.3 设计目标

  • 防止App被各种方式抓包
    • 做好各种防抓包安全措施,避免各种黑科技抓包。
  • 沉淀为技术库复用
    • 目前只是针对App端有需要做防抓包措施,后期其他业务线可能也有这个需要。因此下沉为工具库,傻瓜式调用很有必要。
  • 该库终极设计目标如下所示
    • 第一点:必须是低入侵性,对原有代码改动少,最简单的加入是一行代码设置即可。完全解耦合。
    • 第二点:可以动态灵活配置,支持配置禁止代理,支持配置是否证书校验,支持配置域名合法性过滤,支持拦截器加解密数据。
    • 第三点:可以检测App是否在双开,挂载,Xposed攻击环境
    • 第四点:可以灵活设置加解密的key,可以灵活替换加解密方式,比如目前采用RC4,另一个项目想用DES,可以灵活更换。

1.4 收益分析

  • 抓包库收益
    • 提高产品App的数据安全,必须对数据传输做好安全保护措施和完整性校验,以防止自身数据在网络传输中裸奔,甚至是被三方恶意利用或攻击。
  • 技能的收益
    • 下沉为功能基础库,可以方便各个产品线使用,提高开发的效率。避免跟业务解耦合。傻瓜式调用,低成本接入!

02.市面抓包的分析

2.1 Https三要素

  • 要清楚HTTPS抓包的原理,首先需要先说清楚 HTTPS 实现数据安全传输的工作原理,主要分为三要素和三阶段。
  • Http传输数据目前存在的问题
    • 1.通信使用明文,内容可能被窃听;2.不验证通信方的身份,因此可能遭遇伪装;3.无法证明报文的完整性,所以有可能遭到篡改。
    • image
  • Https三要素分别是:
    • 1.加密:通过对称加密算法实现。
    • 2.认证:通过数字签名实现。(因为私钥只有 “合法的发送方” 持有,其他人伪造的数字签名无法通过验证)
    • 3.报文完整性:通过数字签名实现。(因为数字签名中使用了消息摘要,其他人篡改的消息无法通过验证)
  • Https三阶段分别是:
    • 1.CA 证书校验:CA 证书校验发生在 TLS 的前两次握手,客户端和服务端通过报文获得服务端 CA 证书,客户端验证 CA 证书合法性,从而确认 CA 证书中的公钥合法性(大多数场景不会做双向认证,即服务端不会认证客户端合法性,这里先不考虑)。
    • 2.密钥协商:密钥协商发生在 TLS 的后两次握手,客户端和服务端分别基于公钥和私钥进行非对称加密通信,协商获得 Master Secret 对称加密私钥(不同算法的协商过程细节略有不同)。
    • 3.数据传输:数据传输发生在 TLS 握手之后,客户端和服务端基于协商的对称密钥进行对称加密通信。
  • Https流程图如下
    • image

2.2 抓包核心原理

  • HTTPS抓包原理
    • Fiddler、Charles等抓包工具,其实都是采用了中间人攻击的方案: 将客户端的网络流量代理到MITM(中间人)主机,再通过一系列的面板或工具将网络请求结构化地呈现出来。
  • 抓包Https有两个突破点
    • CA证书校验是否合法;数据传递过程中的加密和解密。如果是要抓包,则需要突破这两点的技术,无非就是MITM(中间人)伪造证书和使用自己的加解密方式。
  • 抓包的工作流程如下
    • 中间人截获客户端向发起的HTTPS请求,佯装客户端,向真实的服务器发起请求;
    • 中间人截获真实服务器的返回,佯装真实服务器,向客户端发送数据;
    • 中间人获取了用来加密服务器公钥的非对称秘钥和用来加密数据的对称秘钥,处理数据加解密。

2.3 搞定CA证书

  • Https抓包核心CA证书
    • HTTPS抓包的原理还是挺简单的,简单来说,就是Charles作为“中间人代理”,拿到了服务器证书公钥和HTTPS连接的对称密钥。
    • 前提是客户端选择信任并安装Charles的CA证书,否则客户端就会“报警”并中止连接。这样看来,HTTPS还是很安全的。
  • 安装CA证书到手机中必须洗白
    • 抓包应用内置的 CA 证书要洗白,必须安装到系统中。而 Android 系统将 CA 证书又分为两种:用户 CA 证书和系统 CA 证书(必要Root权限)。
  • Android从7.0开始限制CA证书
    • 只有系统(system)证书才会被信任。用户(user)导入的Charles根证书是不被信任的。相当于可以理解Android系统增加了安全校验!
  • 如何绕过CA证书这种限制呢?已知有以下四种方式
    • 第一种方式:AndroidManifest 中配置 networkSecurityConfig,App 信任用户 CA 证书,让系统对用户 CA 证书的校验给予通过。
    • 第二种方式:调低 targetSdkVersion < 24,不过这种方式谷歌市场有限制,意味着抓 HTTPS 的包越来越难操作。
    • 第三种方式:挂载App抓包,VirtualApp 这种多开应用可以作为宿主系统来运行其它应用,利用xposed避开CA证书校验。
    • 第四种方式:Root手机,把 CA 证书安装到系统 CA 证书目录中,那这个假 CA 证书就是真正洗白了,难度较大。

2.4 突破CA证书校验

  • App版本如何让证书校验安全
    • 1.设置targetSdkVersion大于24,去掉清单文件中networkSecurityConfig文件中的system和user配置,设置不信任用户证书。
    • 2.公钥证书固定。指 Client 端内置 Server 端真正的公钥证书。在 HTTPS 请求时,Server 端发给客户端的公钥证书必须与 Client 端内置的公钥证书一致,请求才会成功。
      • 证书固定的一般做法是,将公钥证书(.crt 或者 .cer 等格式)内置到 App 中,然后创建 TrustManager 时将公钥证书加进去。
  • 那么如何突破CA证书校验
    • 第一种:JustTrustMe 破解证书固定。Xposed 和 Magisk 都有相应的模块,用来破解证书固定,实现正常抓包。破解的原理大致是,Hook 创建 SSLContext 等涉及 TrustManager 相关的方法,将固定的证书移除。
    • 第二种:基于 VirtualApp 的 Hook 机制破解证书固定。在 VirtualApp 中加入 Hook 代码,然后利用 VirtualApp 打开目标应用进行抓包。具体看:VirtualHook

2.5 如何搞定加解密

  • 目前使用对称加密和解密请求和响应数据
    • 加密和解密都是用相同密钥。只有一把密钥,如果密钥暴露,内容就会暴露。但是这一块逆向破解有些难度。而破解解密方式就是用密钥逆向解密,或者中间人冒充使用自己的加解密方式!
  • 加密后数据镇兼顾了安全性吗
    • 不一定安全。中间人伪造自己的公钥和私钥,然后拦截信息,进行篡改。

2.6 Charles原理

  • Charles类似代理服务器
    • Charles 通过将软件本身设置成系统的网络访问代理服务器,使得所有的网络请求都会走一遍 Charles 代理,从而 Charles 可以截取经过它的请求,然后我们就可以对其进行网络包的分析。
  • 截取设备网络封包数据
    • Charles对应设置:将代理功能打开,并设置一个固定的端口。默认情况下,端口号为:8888 。
    • 移动设备设置:在手机上设置 WIFI 的 HTTP 代理。注意这里的前提是,Phone 和 Charles 代理设备链接的是同一网络(同一个ip地址和端口号)。
  • 截取Https的网络封包
    • 正常情况下,Charles 是不能截取Https的网络包的,这涉及到 Https 的证书问题。

2.7 抓包原理图

  • Charles抓包原理图
    • image
  • Android上的网络抓包原来是这样工作的

2.8 抓包核心流程

  • 抓包核心流程关键节点
    • 第一步,客户端向服务器发起HTTPS请求,charles截获客户端发送给服务器的HTTPS请求,charles伪装成客户端向服务器发送请求进行握手 。
    • 第二步,服务器发回相应,charles获取到服务器的CA证书,用根证书(这里的根证书是CA认证中心给自己颁发的证书)公钥进行解密,验证服务器数据签名,获取到服务器CA证书公钥。然后charles伪造自己的CA证书(这里的CA证书,也是根证书,只不过是charles伪造的根证书),冒充服务器证书传递给客户端浏览器。
    • 第三步,与普通过程中客户端的操作相同,客户端根据返回的数据进行证书校验、生成密码Pre_master、用charles伪造的证书公钥加密,并生成HTTPS通信用的对称密钥enc_key。
    • 第四步,客户端将重要信息传递给服务器,又被charles截获。charles将截获的密文用自己伪造证书的私钥解开,获得并计算得到HTTPS通信用的对称密钥enc_key。charles将对称密钥用服务器证书公钥加密传递给服务器。
    • 第五步,与普通过程中服务器端的操作相同,服务器用私钥解开后建立信任,然后再发送加密的握手消息给客户端。
    • 第六步,charles截获服务器发送的密文,用对称密钥解开,再用自己伪造证书的私钥加密传给客户端。
    • 第七步,客户端拿到加密信息后,用公钥解开,验证HASH。握手过程正式完成,客户端与服务器端就这样建立了”信任“。
  • 在之后的正常加密通信过程中,charles如何在服务器与客户端之间充当第三者呢?
    • 服务器—>客户端:charles接收到服务器发送的密文,用对称密钥解开,获得服务器发送的明文。再次加密, 发送给客户端。
    • 客户端—>服务端:客户端用对称密钥加密,被charles截获后,解密获得明文。再次加密,发送给服务器端。由于charles一直拥有通信用对称密钥enc_key,所以在整个HTTPS通信过程中信息对其透明。

03.防止抓包思路

3.1 先看如何抓包

  • 使用Charles需要做哪些操作
    • 1.电脑上需要安装证书。这个主要是让Charles充当中间人,颁布自己的CA证书。
    • 2.手机上需要安装证书。这个是访问Charles获取手机证书,然后安装即可。
    • 3.Android项目代码设置兼容。Google 推出更加严格的安全机制,应用默认不信任用户证书(手机里自己安装证书),自己的app可以通过配置解决,相当于信任证书的一种操作!
  • 尤其可知抓包的突破口集中以下几点
    • 第一点:必须链接代理,且跟Charles要具有相同ip。思路:客户端是否可以判断网络是否被代理了
    • 第二点:CA证书,这一块避免使用黑科技hook证书校验代码,或者拥有修改CA证书权限。思路:集中在可以判断是否挂载
    • 第三点:冒充中间人CA证书,在客户端client和服务端server之间篡改拦截数据。思路:可以做CA证书校验
    • 第四点:为了可以在7.0上抓包,App往往配置清单文件networkSecurityConfig。思路:线上环境去掉该配置

3.2 设置配置文件

  • 一个是CA证书配置文件
    • debug包为了能够抓包,需要配置networkSecurityConfig清单文件的system和user权限,只有这样才会信任用户证书。
  • 一个是检验证书配置
    • 不论是权威机构颁发的证书还是自签名的,打包一份到 app 内部,比如存放在 asset 里。然后用这个KeyStore去引导生成的TrustManager来提供证书验证。
  • 一个是检验域名合法性
    • Android允许开发者重定义证书验证方法,使用HostnameVerifier类检查证书中的主机名与使用该证书的服务器的主机名是否一致。
    • 如果重写的HostnameVerifier不对服务器的主机名进行验证,即验证失败时也继续与服务器建立通信链接,存在发生“中间人攻击”的风险。
  • 如何查看CA证书的数据

3.3 数据加密处理

  • 网络数据加密的需求
    • 为了项目数据安全性,对请求体和响应体加密,那肯定要知道请求体或响应体在哪里,然后才能加密,其实都一样不论是加密url里面的query内容还是加密body体里面的都一样。
  • 对数据哪里进行加密和解密
    • 目前对数据返回的data进行加解密。那么如何做数据加密呢?目前项目中采用RC4加密和解密数据。
  • 抓取到的内容为乱码
    • 有的APP为了防止抓取,在返回的内容上做了层加密,所以从Charles上看到的内容是乱码。这种情况下也只能反编译APP,研究其加密解密算法进行解密。难度极大!

3.4 避免黑科技抓包

  • 基于Xposed(或者)黑科技破解证书校验
    • 这种方式可以检查是否有Xposed环境,大概的思路是使用ClassLoader去加载固定包名的xp类,或者手动抛出异常然后捕获去判断是否包含Xposed环境。
  • 基于VirtualApp挂载App突破证书访问权限
    • 这个VirtualApp相当于是一个宿主App(可以把它想像成桌面级App),它突破证书校验。然后再实现挂载App的抓包。判断是否是双开环境!

04.防抓包实践开发

4.1 App安全配置

  • 添加配置文件
    • android:networkSecurityConfig="@xml/network_security_config"
  • 配置networkSecurityConfig抓包说明
    • 中间人代理之所有能够获取到加密密钥就是因为我们手机上安装并信任了其代理证书,这类证书安装后都会被归结到用户证书一类,而不是系统证书。
    • 那我们可以选择只信任系统内置的系统证书,而屏蔽掉用户证书(Android7.0以后就默认是只信任系统证书了),就可以防止数据被解密了。
  • 实现App防抓包安全配置方式有两种:
    • 一种是Android官方提供的网络安全配置;另一种也可以通过设置网络框架实现(以okhttp为例)。
    • 第一种:具体可以看清单配置文件,相当于base-config标签下去掉 这组标签。
    • 第二种:需要给okhttpClient配置 X509TrustManager 来监听校验服务端证书有效性。遍历设备上信任的证书,通过证书别名将用户证书(别名中含有user字段)过滤掉,只将系统证书添加到验证列表中。
  • 该方案优点和缺点分析说明
    • 优点:network_security_config配置简单,对整个app网络生效,无需修改代码;代码实现对通过该网络框架请求的生效,能兼容7.0以前系统。
    • 缺陷:network_security_config配置方式,7.0以前的系统配置不生效,依然可以通过代理工具进行抓包。okhttp配置的方式只能对使用该网络框架进行数据传输的接口生效,并不能对整个app生效。
    • 破解:将手机进行root,然后将代理证书放置到系统证书列表内,就可以绕过代码或配置检查了。

4.2 关闭代理

  • charles 和 fiddler 都使用代理来进行抓包,对网络客户端使用无代理模式即可防止抓包,如
    OkHttpClient.Builder()
        .proxy(Proxy.NO_PROXY)
        .build()
  • no_proxy实际上就是type属性为direct的一个proxy对象,这个type有三种
    • direct,http,socks。这样因为是直连,所以不走代理。所以charles等工具就抓不到包了,这样一定程度上保证了数据的安全,这种方式只是通过代理抓不到包。
  • 通常情况下上述的办法有用,但是无法防住使用 VPN 导流进行的抓包
    • 使用VPN抓包的原理是,先将手机请求导到VPN,再对VPN的网络进行Charles的代理,绕过了对App的代理。
  • 该方案优点和缺点分析说明
    • 优点:实现简单方便,无系统版本兼容问题。
    • 缺陷:该方案比较粗暴,将一切代理都切断了,对于有合理诉求需要使用网络代理的场景无法满足。
    • 破解:使用ProxyDroid全局代理工具通过iptables对请求进行强制转发,可以有效绕过代理检测。

4.3 证书校验(单向认证)

  • 下载服务器端公钥证书
    • 为了防止上面方案可能导致的“中间人攻击”,可以下载服务器端公钥证书,然后将公钥证书编译到Android应用中一般在assets文件夹保存,由应用在交互过程中去验证证书的合法性。
  • 如何设置证书校验
    • 通过OkHttp的API方法 sslSocketFactory(sslSocketFactory,trustManager) 设置SSL证书校验。
  • 如何设置域名合法性校验
    • 通过OkHttp的API方法 hostnameVerifier(hostnameVerifier) 设置域名合法性校验。
  • 证书校验的原理分析
    • 按CA证书去验证的,若不是CA可信任的证书,则无法通过验证。
  • 单向认证流程图
    • image
  • 该方案优点和缺点分析说明
    • 优点:安全性比较高,单向认证校验证书在代码中是方便的,安全性相对较高。
    • 缺陷:CA证书存在过期的问题,证书升级。
    • 破解:证书锁定破解比较复杂,比如老牌的JustTrustMe插件,通过hook各网络框架的证书校验方法,替换原有逻辑,使校验失效。

4.4 双向认证

  • 什么叫做双向认证
    • SSL/TLS 协议提供了双向认证的功能,即除了 Client 需要校验 Server 的真实性,Server 也需要校验 Client 的真实性。
  • 双向认证的原理
    • 双向认证需要 Server 支持,Client 必须内置一套公钥证书 + 私钥。在 SSL/TLS 握手过程中,Server 端会向 Client 端请求证书,Client 端必须将内置的公钥证书发给 Server,Server 验证公钥证书的真实性。
    • 用于双向认证的公钥证书和私钥代表了 Client 端身份,所以其是隐秘的,一般都是用 .p12 或者 .bks 文件 + 密钥进行存放。
  • 代码层面如何做双向认证
    • 双向校验就是自定义生成客户端证书,保存在服务端和客户端,当客户端发起请求时在服务端也校验客户端的证书合法性,如果不是可信任的客户端发送的请求,则拒绝响应。
    • 服务端根据自身使用语言和网络框架配置相应证书校验机制即可。
  • 双向认证流程图
    • image
  • 该方案优点和缺点分析说明
    • 优点:安全性非常高,使用三方工具不易破解。
    • 缺陷:服务端需要存储客户端证书,一般服务端会对应多个客户端,就需要分别存储和校验客户端证书,增加校验成本,降低响应速度。该方案比较适合对安全等级要求比较高的业务(如金融类业务)。
    • 破解:由于在服务端也做校验,在服务端安全的情况下很难被攻破。

4.5 防止挂载抓包

  • Xposed是一个牛逼的黑科技
    • Xposed + JustTrustMe 可以破解绕过校验CA证书。那么这样CA证书的校验就形同虚设了,对App的危险性也很大。
  • App多开运行在多个环境上
    • 多开App的原理类似,都是以新进程运行被多开的App,并hook各类系统函数,使被多开的App认为自己是一个正常的App在运行。
    • 一种是从多开App中直接加载被多开的App,如平行空间、VirtualApp等,另一种是让用户新安装一个App,但这个App本质上就是一个壳,用来加载被多开的App。
  • VirtualApp是一个牛逼的黑科技
    • 它破坏了Android 系统本身的隔离措施,可以进行免root hook和其他黑科技操作,你可以用这个做很多在原来APP里做不到事情,于此同时Virtual App的安全威胁也不言而喻。
  • 如何判断是否具有Xposed环境
    • 第一种方式:获取当前设备所有运行的APP,根据安装包名对应用进行检测判断是否有Xposed环境。
    • 第二种方式:通过自造异常来检测堆栈信息,判断异常堆栈中是否包含Xposed等字符串。
    • 第三种方式:通过ClassLoader检查是否已经加载了XposedBridge类和XposedHelpers类来检测。
    • 第四种方式:获取DEX加载列表,判断其中是否包含XposedBridge.jar等字符串。
    • 第五种方式:检测Xposed相关文件,通过读取/proc/self/maps文件,查找Xposed相关jar或者so文件来检测。
  • 如何判断是否是双开环境
    • 第一种方式:通过检测app私有目录,多开后的应用路径会包含多开软件的包名。还有一种思路遍历应用列表如果出现同样的包名,则被认为双开了。
    • 第二种方式:如果同一uid下有两个进程对应的包名,在"/data/data"下有两个私有目录,则该应用被多开了。
  • 判断了具有xposed或者多开环境怎么处理App
    • 目前使用VirtualApp挂载,或者Xposed黑科技去hook,前期可以先用埋点统计。测试学而思App发现挂载在VA上是推出App。

4.5 数据加解密

  • 针对数据加解密入口
    • 目前在网络请求类里添加拦截器,然后在拦截器中处理request请求和response响应数据的加密和解密操作。
  • 主要是加密什么数据
    • 在request请求数据阶段,如果是get请求加密url数据,如果是post请求则加密url数据和requestBody数据。
    • 在response响应数据阶段,
  • 如何进行加密:发起请求(加密)
    • 第一步:获取请求的数据。主要是获取请求url和requestBody,这一块需要对数据一块处理。
    • 第二步:对请求数据进行加密。采用RC4加密数据
    • 第三步:根据不同的请求方式构造新的request。使用 key 和 result 生成新的 RequestBody 发起网络请求
  • 如何进行解密:接收返回(解密)
    • 第一步:常规解析得到 result ,然后使用RC4工具,传入key去解密数据得到解密后的字符串
    • 第二步:将解密的字符串组装成ResponseBody数据传入到body对象中
    • 第三步:利用response对象去构造新的response,然后最后返回给App

4.7 证书锁定

  • 证书锁定是Google官方比较推荐的一种校验方式
    • 原理是在客户端中预先设置好证书信息,握手时与服务端返回的证书进行比较,以确保证书的真实性和有效性。
  • 如何实现证书锁定
    • 有两种实现方式:一种通过network_security_config.xml配置,另一种通过代码设置;
    //第一种方式:配置文件
    <network-security-config>
        <domain-config>
            <domain includeSubdomains="true">api.zuoyebang.cn</domain>
            <pin-set expiration="2025-01-01">
                <pin digest="SHA-256">38JpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhK90=</pin>
                <!-- 备用证书信息,般为域名证书的二级证书 -->
                <pin digest="SHA-256">9k1a0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM90K=</pin>
            </pin-set>
        </domain-config>
    </network-security-config>
    
    //第二种方式:代码设置
    fun sslPinning(): OkHttpClient {
        val builder = OkHttpClient.Builder()
        val pinners = CertificatePinner.Builder()
            .add("api.zuoyebang.cn", "sha256//89KpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRh00L=")
            .add("api.zuoyebang.com", "sha256//a8za0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1o=09")
            .build()
        builder.apply {
            certificatePinner(pinners)
        }
        return builder.build()
    }
  • 该方案优点和缺点分析说明
    • 优点:安全性高,配置方式也比较简单,并能实现动态更新配置。
    • 缺陷:网络安全配置无法实现证书证书的动态更新,另外该配置也受Android系统影响,对7.0以前的系统不支持。代码配置相对灵活些。
    • 破解:证书锁定破解比较复杂,比如老牌的JustTrustMe插件,通过hook各网络框架的证书校验方法,替换原有逻辑,使校验失效

4.8 Sign签名

  • 先说一下背景和问题
    • http://api.test.com/getbanner?key1=value1&key2=value2&key3=value3
    • 这种方式简单粗暴,通过调用getbanner方法即可获取轮播图列表信息,但是这样的方式会存在很严重的安全性问题,没有进行任何的验证,大家都可以通过这个方法获取到数据,导致产品信息泄露。
  • 在写开放的API接口时是如何保证数据的安全性的?
    • 请求来源(身份)是否合法?请求参数被篡改?请求的唯一性(不可复制)?
  • 问题的解决方案设想
    • 解决方案:为了保证数据在通信时的安全性,我们可以采用参数签名的方式来进行相关验证。
  • 最终决定的解决方案
    • 调用接口之前需要验证签名和有效时间,要生成一个sign签名。先拼接-后转码-再加密-再发请求!
  • sign签名校验实践
    • 需要对请求参数进行签名验证,签名方式如下:key1=value1&key2=value2&key3=value3&secret=yc 。对这个字符串进行md5一下。
    • 然后被sign后的接口就变成了:http://api.test.com/getbanner?key1=value1&key2=value2&key3=value3&sign=xxx
    • 为什么在获取sign的时候建议使用secret参数?secret仅作加密使用,添加在参数中主要是md5,为了保证数据安全请不要在请求参数中使用。
  • 服务端对sign校验
    • 这样请求的时候就需要合法正确签名sign才可以获取数据。这样就解决了身份验证和防止参数篡改问题,如果请求参数被人拿走,没事,他们永远也拿不到secret,因为secret是不传递的。再也无法伪造合法的请求。
  • 如何保证请求的唯一性
  • Sign签名安全性分析:
    • 通过上面的案例,安全的关键在于参与签名的secret,整个过程中secret是不参与通信的,所以只要保证secret不泄露,请求就不会被伪造。

05.架构设计说明

5.1 整体架构设计

5.2 关键流程图

5.3 稳定性设计

  • 对于请求和响应的数据加解密要注意
    • 在网络上交换数据(网络请求数据)时,可能会遇到不可见字符,不同的设备对字符的处理方式有一些不同。
    • Base64对数据内容进行编码来适合传输。准确说是把一些二进制数转成普通字符用于网络传输。统统变成可见字符,这样出错的可能性就大降低了。

5.4 降级设计

  • 可以一键配置AB测试开关
    .setMonitorToggle(object : IMonitorToggle {
        override fun isOpen(): Boolean {
            //todo 是否降级,如果降级,则不使用该功能。留给AB测试开关
           return false
        }
    })
    

5.5 异常设计说明

  • base64加密和解密导致错误问题
    • Android 有自带的Base64实现,flag要选Base64.NO_WRAP,不然末尾会有换行影响服务端解码。导致解码失败。

5.6 Api文档

  • 关于初始化配置
    NotCaptureHelper.getInstance().config = CaptureConfig.builder()
            //设置debug模式
        .setDebug(true)
            //设置是否禁用代理
        .setProxy(false)
            //设置是否进行数据加密和解密,
        .setEncrypt(true)
            //设置cer证书路径
        .setCerPath("")
            //设置是否进行CA证书校验
        .setCaVerify(false)
            //设置加密和解密key
        .setEncryptKey(key)
            //设置参数
        .setReservedQueryParam(OkHttpBuilder.RESERVED_QUERY_PARAM_NAMES)
        .setMonitorToggle(object : IMonitorToggle {
            override fun isOpen(): Boolean {
                //todo 是否降级,如果降级,则不使用该功能。留给AB测试开关
               return false
            }
        })
        .build()
  • 设置okHttp配置
    NotCaptureHelper.getInstance().setOkHttp(app,okHttpBuilder)
  • 如何设置自己的加解密方式
    NotCaptureHelper.getInstance().encryptDecryptListener = object : EncryptDecryptListener {
        /**
         * 外部实现自定义加密数据
         */
        override fun encryptData(key: String, data: String): String {
            LoggerReporter.report("NotCaptureHelper", "encryptData data : $data")
            val str = data.encryptWithRC4(key) ?: ""
            LoggerReporter.report("NotCaptureHelper", "encryptData str : $str")
            return str
        }
        /**
         * 外部实现自定义解密数据
         */
        override fun decryptData(key: String, data: String): String {
            LoggerReporter.report("NotCaptureHelper", "decryptData data : $data")
            val str = data.decryptWithRC4(key) ?: ""
            LoggerReporter.report("NotCaptureHelper", "decryptData str : $str")
            return str
        }
    }

5.7 防抓包功能自测

  • 网络请求测试
    • 正常请求,测试网络功能是否正常
  • 抓包测试
    • 配置fiddler,charles等工具
    • 手机上设置代理
    • 手机上安装证书
    • 单向认证测试:进行网络请求,会提示SSLHandshakeException即ssl握手失败的错误提示,即表示app端的单向认证成功。
    • 数据加解密:进行网络请求,看一下请求参数和响应body数据是否加密,如果看不到实际json实体则表示加密成功。

More Repositories

1

YCBlogs

技术博客笔记大汇总,包括Java基础,线程,并发,数据结构;Android技术博客等等;常用设计模式;常见的算法;网络协议知识点;部分flutter笔记;还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!转载请注明出处,谢谢!
6,368
star
2

YCAppTool

组件化综合案例,组件分层为:基础公共组件,功能组件,业务组件,主工程。每一层组件的建设,很详细的工程案例,很全面的一个组件化实践案例。一个超级综合案例!
Java
3,157
star
3

YCVideoPlayer

基础封装视频播放器player,可以在ExoPlayer、MediaPlayer原生MediaPlayer可以自由切换内核;该播放器整体架构:播放器内核(自由切换) + 视频播放器 + 边播边缓存 + 高度定制播放器UI视图层。支持视频简单播放,列表播放,仿抖音滑动播放,自动切换播放,使用案例丰富,拓展性强。
Java
2,162
star
4

YCWebView

基于腾讯x5开源库,提高webView开发效率,大概要节约你百分之六十的时间成本。该案例支持处理js的交互逻辑且无耦合、同时暴露进度条加载进度、可以监听异常error状态、支持视频播放并且可以全频、支持加载word,xls,ppt,pdf,txt等文件文档、发短信、打电话、发邮件、打开文件操作上传图片、唤起原生App、支持webView页面截图、x5库为最新版本,功能强大。
Java
1,725
star
5

YCAndroidTool

用于项目测试,崩溃重启操作,崩溃记录日志【可以查看,分享】和重启【多种重启app方式】;网路拦截查看的工具小助手,拦截请求和响应数据,统计接口请求次数,流量消耗,以及统计网络链接/dns解析/request请求/respond响应等时间。提高开发效率……
Java
739
star
6

YCStateLayout

State switching, so that the View state switch and Activity completely separate. Using builder mode to freely add the required state View, can set data, data is empty, load data error, network error, load and other states, and support the layout of custom state. At present has been used in other formal projects, strong expansion!
Java
558
star
7

YCSlideLayout

购物商场商品详情页面自定义控件,模仿淘宝、京东、考拉等商品详情页分页加载的UI效果。可以嵌套RecyclerView、WebView、ViewPager、ScrollView等等。支持设置上拉分页加载动画效果……
Java
490
star
8

YCCustomText

自定义文本控件,支持富文本,包含两种状态:编辑状态和预览状态。编辑状态中,可以对插入本地或者网络图片,可以同时插入多张有序图片和删除图片,支持图文混排,并且可以对文字内容简单操作加粗字体,设置字体下划线,支持设置文字超链接(超链接支持跳转),已经用于多个实际项目中……
Java
478
star
9

YCRefreshView

自定义支持上拉加载更多,下拉刷新,可以自定义头部和底部,可以添加多个headerView,使用一个原生recyclerView就可以搞定复杂界面。支持自由切换状态【加载中,加载成功,加载失败,没网络等状态】的控件,可以自定义状态视图View。拓展功能【支持长按拖拽,侧滑删除】,轻量级,可以选择性添加 。多年前已经使用于前项目投资界,新芽,沙丘大学等APP正式项目中!持续更新……
Java
454
star
10

YCUpdateApp

轻量级版本更新弹窗,弹窗上支持更新进度条,可以设置普通更新或者强制更新。解决8.0以上通知栏不显示问题,解决7.0以上安装apk异常,下载完成则会自动提示安装;下载异常,失败,错误等状态,支持重启下载任务;还支持自定义下载路径。代码量少,调用简单……
Java
447
star
11

YCNotification

通知栏封装库,强大的通知栏工具类,链式编程调用,解决了8.0以上通知栏不显示问题,支持多种不同的使用场景,兼容老版本。还有自定义通知栏view,可高度定制布局……
Java
375
star
12

YCScrollPager

仿抖音,快手,短视频,竖直方向,一次滚动一个页面的封装库。目前支持ViewPager做法,也支持RecyclerView做法……使用ViewPager则只是修改滑动速率,以及滚动翻页过渡时间;使用recyclerView打造丝滑切换视频的功能,更多内容可以看demo
Java
373
star
13

YCDialog

自定义弹窗,其中包括:自定义Toast;自定义dialog控件;自定义DialogFragment弹窗;自定义PopupWindow弹窗;还有自定义Snackbar等等;简单便用。目前已经用于多个正式项目中。
Java
358
star
14

YCAudioPlayer

音频播放器,基础播放功能有:播放,暂停,下一首,上一首;可以设置多种播放类型:顺序播放,随机播放,单曲循环;可以设置播放进度快慢,参考混沌大学APP;支持后台播放,可以扫描本地音频,有效处理了捕获/丢弃音频焦点逻辑,支持耳机线控。通知栏,底部音频播放控制栏,音频List页面和播放详情页数据同步。持续更新中……
Java
347
star
15

YCStatusBar

关于状态栏方案总结案例,适合于绝大多数的使用场景……同时,兼容了小米,魅族等手机状态栏字体颜色设置失效问题。已经用于实际项目投资界,新芽,沙丘大学等APP,一键集成并使用!支持单Activity多Fragment动态修改状态栏颜色,入侵性低,一行代码即可实现你需要的需求
Java
312
star
16

YCJniHelper

JNI学习案例,通过简单的案例快速入门jni开发。JNI基础语法介绍,so库生成打包和反编译,Java和C/C++相关调用案例
Java
263
star
17

YCFlutterUtils

Flutter Utils 全网最齐全的工具类。包含bus,颜色,日期,文件,json,log,sp,加解密,num,图片,网络,正则,验证,路由,文本,时间,spi,计时器,拓展类,编解码,发射,异常,字节转化,解析等等工具类。
Dart
240
star
18

YCThreadPool

轻量级简易线程池库,轻量级线程池异步库,支持线程执行过程中状态回调监测(包含成功,失败,异常等多种状态);支持创建异步任务,可以设置线程的名称,延迟执行时间,线程优先级,回调callback等;可以根据自己需要创建自己需要的线程池;线程异常时,可以打印异常日志,避免崩溃。
Java
224
star
19

YCCommonLib

组件化开发中基础公共库,activity栈管理;fragment周期监听;Lru缓存库;反射库;分区存储;Log日志打印和存储;通用缓存库(支持sp,mmkv,lru,disk,fastsp等多种存储方式切换);App重启;通用全面的工具类Utils;通用基类fragment,adpater,activity等简单封装;intent内容打印到控制台库;通用基础接口
Java
190
star
20

YCWidgetLib

自定义控件,其中包含自定义折叠布局,拓展性强使用简单;万能自定义红点控件,充分解耦合接入方便;多种方案实现阴影效果库;自定义view和viewGroup圆角控件,彻底解决圆角问题等
Java
184
star
21

YCWalleHelper

瓦力多渠道打包的Python脚本测试工具,通过该自动化脚本,自需要run一下或者命令行运行脚本即可实现美团瓦力多渠道打包,打包速度很快。配置信息十分简单,代码中已经注释十分详细。可以自定义输出文件路径,可以修改多渠道配置信息,简单实用。
Tcl
133
star
22

YCBannerView

轮播图,支持多种自定义属性,可以设置轮播红点或者轮播数字,支持设置引导页。可以根据不同使用场景,可以选择无限循环,静态管理或者动态管理adapter,还可以设置暂停和开始轮播。后期添加了RecyclerView轮播图,同时自定义多种类型SnapHelper,卡片滑动流畅,目前已经用于多个正式项目中!!
Java
106
star
23

YCModelBus

组件之间的通信,很友好起到隔离效果,接口+实现类,使用注解生成代码方式,无需手动注册,将使用步骤简单化,支持组件间以暴露接口提供服务的方式进行通信。
Java
77
star
24

YCHybridFlutter

Android和flutter混合开发案例
Dart
71
star
25

YCToolLib

通用工具库组件,包括前后台判断,拦截器时间,心跳轮询库,Task任务库,二维码扫码库,转场动画库,通用TTS音频播放库,国际化locale库等等
Java
60
star
26

YCStudyC

系统性学习C/C++编程语音,记录的Demo案例和学习笔记
C++
48
star
27

YCServerLib

gRPC学习案例,使用gRPC作为网络方案可以带来高效性、跨平台和语言、可靠性、易于使用和可扩展性等收益。同时可以减少手动编写代码的工作量,提高开发效率。
Java
48
star
28

YCDesignHelper

注解学习小案例,比较系统性学习注解并且应用实践。简单应用了运行期注解,通过注解实现了setContentView功能;简单应用了编译器注解,通过注解实现了防暴力点击的功能,同时支持设置时间间隔;使用注解替代枚举;使用注解一步步搭建简单路由案例。结合相应的博客,在来一些小案例,从此应该对注解有更加深入的理解……
Java
45
star
29

YCArchitecture

MVC,MVP,MVVM框架案例实践,Jetpack,Compose等学习演进。不同架构案例demo对比……
Java
44
star
30

YCTimerHelper

倒计时工具,分别使用了handler,自定义CountDownTimer,Timer和TimerTask,chronometer控件,和属性动画实现倒计时的功能。封装CountDownTimer倒计时器【在原有基础上增加了暂停和恢复倒计时功能】,解决了倒计时无法到0和从最大值开始bug
Java
13
star
31

YCVaHelpTool

VA学习案例,研究挂载,逆向,安全这一块
Java
5
star
32

YCSplashSdk

打开app启动页sdk,支持图片广告,也支持视频
3
star
33

YCUniApp

uni开发的项目,由于公司项目做混合开发,因此边学边做。基础入门级的案例分析,近期学习更新中
Vue
3
star
34

YCPluginTool

Plugin插件学习工具
2
star
35

yangchong211

1
star