关于前端:????-如何隐藏你的热更新-bundle-文件

如果你喜爱我的文章,心愿点赞???? 珍藏 ???? 在看 ???? 三连反对一下!!!谢谢你,这对我真的很重要!

前段时间咱们公司的一个大佬从一些渠道得悉了一些小道消息,某国民级 APP 因为 Apple App Store 审核人员检测出 React Native 热更新的内容,被拒审了三个月。咱们的热更新平台和出事的 APP 原理类似,所以也存在着拒审危险。那么咱们就要想一些方法,暗藏热更新 bundle,不被审核人员发现。

其实这个问题蛮简单的,因为它不单纯是一个技术问题,还波及到各种简单的商业利益,在诸多的限度条件下,你很难去找到一个最优解。而且这个问题也比拟敏感,我也只能大抵讲一下我的思路,具体的代码实现本文也不会提供。

郑重声明 ⚠️:若有人按本文思路暗藏热更新数据导致利用拒审或下架,自己概不负责

<!–truncate–>

一、商业利益

Apple 公司对 iPhone 生态有着十分严格的管控:App 上架必须走 App Store,动态链接库要参加签名,带 JIT 性能的虚拟机不能用……

对于热更新技术,Apple 在 2017 年封杀过一次 JSPatch 这个热更新框架,导致很多的 APP 被拒审,依据 Apple 官网给出的理由,次要有三点:

  • 热更新代码没有做好加密和校验,有可能被第三方破解劫持
  • JSPatch 权限过高,可能会调用公有 API,扭转原有的 APP 性能
  • 对于 Apple 官网来说,JSPatch 自由度太大,会绕过 App Store 这个 iOS 上的惟一流量散发平台更新利用,影响商业利益

俗话说得好,断人财路如杀人父母,这种波及商业利益的事件无论放在谁都头上都忍不了,而且很多利用又不是微信,有宏大的用户基数能够和 Apple 官网会谈(微信小程序生态就是谈进去的,然而小程序领取权限就没谈妥),所以说这个问题还是很简单的。

其实对于 Apple 官网来说,对与动态化热更新的态度向来是不赞成也不拥护,和 JSPatch 比起来,React Native 和游戏热更新这两种利用场景还是被容许的,次要还是体现在三点:

  • 网游这种重经营的场景还是须要热更新维持流动热度的,每周都有新流动,让用户被动去 App Store 下载更新包很不合理,App 流动经营同理
  • React Native/Lua 等热更新技术是在一个容器里进行动态化的,不像 JSPatch 有那么大的批改权限
  • 苹果官网在商业利益上和游戏厂商/互联网巨头达到一些奥妙的均衡

说实话苹果审核始终很迷,拒审有时候和打太极一样,给出的标准各路解读都不一样,不过为了保险起见,咱们还是要钻研一下相干的平台标准。

二、解读标准

2015 年苹果发过一篇协定——《Apple Developer Program License Agreement》,文中第 3.3.2 节有一段对于热更新的内容:

Except as set forth in the next paragraph, an Application may not download or install executable code. Interpreted code may only be used in an Application if all scripts, code and interpreters are packaged in the Application and not downloaded. The only exceptions to the foregoing are scripts and code downloaded and run by Apple’s built-in WebKit framework or JavascriptCore, provided that such scripts and code do not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application as submitted to the App Store.

这一段话大略就是说除了 Webkit 和 JavascriptCore 能够动静执行下发的脚本和文件,其它所有脚本/代码/解释器都必须打包在 APP 外部。这句话其实就给 React Native 留了一个口子:React Native 就是用 JavascriptCore 执行 JS 脚本文件的,那么动静下发也是正当的。

Interpreted code may be downloaded to an Application but only so long as such code: (a) does not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application as submitted to the App Store, (b) does not create a store or storefront for other code or applications, and (c) does not bypass signing, sandbox, or other security features of the OS.

这一段话大略就是说,我容许你热更新,然而必须遵循我这三条规定:

  • 不能大的批改 APP 性能,导致利用理论性能和 APP Store 的宣传不符(这个中央就很打太极,评判规范全靠审核人员情绪)
  • 不能动态创建利用商店(应该是不能绕过 IAP 领取的意思,要不然怎么收苹果税)
  • 不能绕过签名/沙箱/OS 的平安性能(这个能够了解,保护零碎和生态平安)

这样解读下来,貌似只有依照标准当个良民就能够解决问题了。然而说实话,动态化标准更多的是小人协定,如果单方都讲武德,那大家其乐融融都挺好;万一哪个人跳进去要坏规矩,说实话大家都很难堪。在将来,热更新技术必定还是要以奥妙的均衡状态存在上来。

三、技术实现

每次设计一些工程计划时,我集体的习惯都是先从实践上找答案。就拿暗藏热更新 bundle 这个例子来说,咱们次要是想在信息传输这里找到突破口,实际上香农老爷子 1949 年就提出了一个「香农一韦弗通信模型」。这个模型里把通信分为五个局部:信息源发射器信道接收器信息接受者乐音

那么联合这个通信模型,咱们暗藏/加密通信信息的答案就跃然纸上了:

  • 对信源加密:在信息的收发终端发送音讯时加密,承受音讯时解密
  • 对信道加密:信息在信道传输时,通过信道时进行加密

那么咱们上面就对这两个大方向进行扩大和探讨。

1.对音讯自身加密/混同

1.1 隐写术——当代特洛伊木马

隐写术是一个十分十分古老的技术,这个技术的要害就是把想要传递的数据暗藏/假装一下,不让第三方看进去实在想要传递的数据。

隐写术的例子十分多,比如说特洛伊木马,你从里面看是个木马,但运到城里,士兵就跑进去了;咱们看的一些影视剧里,也有相似原理的桥段:配角收到一份无字信纸,在蜡烛上一烤,文字就显现出来。现在的数字时代必定不会用无字信纸机密传递音讯,咱们必定有些更加赛博的办法,比如说图种技术——把音讯隐写到图片文件里

如果大家玩过一段时间贴吧,对图种技术必定不会生疏,有些大神会发个贴,把种子文件暗藏在图片里,大家把图片下载下来,把 .jpg 的后缀改为 .zip or .rar,而后解压文件就能失去暗藏的种子文件,而后在贴吧留下「楼主坏蛋」的美誉。

那么图种技术的原理是啥?其实很简略,它只是单纯的把一个 jpg 文件和一个 rar 文件合并在一起,然而图片查看器会疏忽附加的 rar 文件数据,这样在感官上这是一张图片,然而从二进制的角度看这个图片文件里暗藏了一些数据。

上面咱们看看图种文件的原理。

首先我用图片编辑器生成一个 2x2 4 个像素大小的图片——RGBY.jpg。色彩我参考 Google logo 配了一下:

而后咱们用二进制查看工具(我这里用的是 Hex Fiend 软件)查看这个图片的编码,因为图片只有 4 个像素,所以二进制数据也会比拟小,留神察看这个文件的二进制数据,它是 FF D8 结尾,FF D9 结尾的。

图片查看器加载一张图片文件时就会做检测,如果是 FF D8 结尾,就会认为这是一张 jpg 图片,而后就会进入 jpg 图片解码的分支,加载二进制数据遇到 FF D9 后,就会认为这个图片曾经加载结束,前面的数据就不会再管了

基于图片预览器不会加载 FF D9 之后数据的这个个性,咱们能够把一些要暗藏的数据附加到 jpg 文件之后。

这里为了测试不便,我新建了一个内容为 hello wordtext.txt 文件,而后用 cat 命令把 RGBY.jpgtext.txt 合并一下,生成 RGBY_text.jpg 文件:

cat RGBY.jpg text.txt > RGBY_text.jpg

这时候用图片浏览器查看文件,能够看出文件还是失常预览的:

然而用二进制查看工具查看这张图片,就会发现他在开端多了 11 个字节,正是 text.txt 里的内容—— hello word

这样咱们就达到了隐写的目标。

大家不要感觉这个计划 low,实际上阿里的一些密钥就是通过相似的原理写到一张图片里的(当然不会像以上案例那么简略)。咱们在传输热更新 bundle 文件时,能够把 bundle 文件隐写在一张图片里,这样审核人员在做流量监控的时候,抓包看到的是一张图片,如果不查看图片的二进制编码,是不会发现外面暗藏了数据的。

针对这种计划,服务端和客户端的改变都比拟小,服务端只须要每次下发 bundle 时前合并一个图片文件,客户端读取隐写图片后去掉多余的图片数据就能够了。

当然隐写术还有很多种,比如说基于 LSB 的图片隐写技术,把数据写在 jpg png mp4 的裁减数据字段里,因为原理大同小异,这里就不多介绍了,感兴趣的同学能够自行搜寻学习。

1.2 对称加密

对称加密也是一个历史悠久的加密技术,在信息技术的加持了下也飞速发展,我举个最简略的对称加密算法——异或算法加密

异或运算我想每一个程序员都不生疏,咱们先约定 0 为 false, 1 为 true,那么 XOR 运算的真值表如下:

A B A ⊕ B
0 0 0
0 1 1
1 0 1
1 1 0

从真值表能够很容易推出上面的运算法令:

$$A \oplus 0=A$$

$$A \oplus A=0$$

$$(A \oplus B) \oplus C=A \oplus(B \oplus C)$$

使用下面的运算规定,咱们假如 $A$ 是密钥,对内容 $B$ 加密,那么失去的密文就是 $(B \oplus A)$;想对密文解密,只有让密文和密钥 $A$ 再进行一次异或运算就能够了:$(B \oplus A) \oplus A=B \oplus 0=B$

咱们能够用代码举例子验算一下:

// 加密:
// 原文       密钥       秘文
01010111 ^ 11110011 = 10100100

// 解密:
// 秘文       密钥       原文 
10100100 ^ 11110011 = 01010111

家喻户晓,位运算都是十分快的,如果要简略地对 bundle 做个混同,间接用异或加密,基本上不会影响性能。

尽管异或运算很简略,然而密码学有个第一准则:永远不要本人实现加密算法。咱们能够用曾经十分成熟的对称加密算法(例如 AES 和 DES)对 bundle 进行加密:性能高,安全性好,最重要的是开源社区都有现成的库,间接调包就能够了。

所以如果用对称加密的计划,只有服务端和客户端磋商好一个密钥,而后服务端用密钥加密 bundle,客户端用同一个密钥解密,就能在肯定水平上绕过 App Store 的异样流量检测。

1.3 非对称加密

非对称加密是属于近代密码学的内容了,十分的新,然而也十分的牢靠,具体原理太简单了,一句两句基本说不清楚,我就不做介绍了。

在加密热更新 bundle 这个场景下,其实和对称加密的成果差不多,只不过换成私钥加密公钥解密了。

1.4 总结

一般来说,对 bundle 加密不会单纯应用一种技术,比如说咱们会用混合加密的形式对 bundle 自身加密,用音讯认证码(例如 HMAC)防篡改,退出工夫戳随机数防重放,最初再把加密后的数据进行隐写……这外面的组合切实是太多了,集体认为参考一些经典的加密组合进行业务实际即可。

2.对信道加密

信道加密在本文的场景下也比拟直观,就是应用 HTTPS 协定,目标就是避免审核人员通过抓包的形式捕捉到咱们的热更新流量。当然 HTTPS 也有很多的有意思的知识点,上面我就简略介绍一下。

2.1 应用 HTTPS

2021 年了,我想互联网上根本没有袒露的 HTTP 明文流量了吧……前几年可能还会有企业思考 HTTPS 加密带来的服务器老本,但在各大平台(iOS/Android/Chrome)的要求下,除了个别无人保护的网站,根本都全站上 HTTPS 了,毕竟当初数据的价值远远高于服务端的电费,上了 HTTPS 后,起码被中间人攻打被劫持的概率会升高不少。

上 HTTPS 就居安思危了吗?那必定不是。我去年写过一篇 Charles 抓包的文章,外面花了大量的篇幅去介绍 HTTPS 抓包。既然一个 APP 开发者能够借助市场上的工具进行抓包,那么审核人员更能够了。在抓包工具下,大部分 HTTPS 数据都能够被捕捉和劫持。上面咱们就说说 HTTPS 协定中一些比拟高阶的内容。

2.2 HTTPS 证书固定

HTTPS 证书固定,又叫 HTTPS 证书锁定,英文名为 Certificate Pinning,指的是咱们在 APP 内置仅承受指定域名的证书,而不承受操作系统或浏览器内置的CA根证书对应的任何证书。

通过这种受权形式,咱们能够保障 APP 与服务端通信的唯一性和安全性。如果开启了抓包软件,不被动导入固定的证书,就无奈无效的抓包(具体原理可看我的博文:Charles 抓包原理)。我想审核人员还没那个精力去砸壳你的 APP 获取你的证书,所以能够通过这种形式暗藏你的热更新 bundle。

当然,证书固定也是有肯定代价的。CA 签发证书都存在有效期问题,所以毛病是在证书续期后须要将证书从新内置到 APP 中。

2.3 HTTPS 双向认证

咱们平时应用 HTTPS 时,个别只做了单向认证,即客户端认证服务端的真实性。其实 HTTPS 反对双向认证的,即反对服务端认证客户端的真实性(具体流程可见下图 * 局部)。

一般来说开启 HTTPS 双向认证的 APP 都是那种安全性要求极高的 APP,比如说金融类 APP 和匿名社交类 APP。而且想要实现双向认证,就必须要在客户端内置一份公钥证书和私钥,但 APP 又有砸壳危险,所以还得想方法把这两个货色加密和隐写(都成俄罗斯套娃了)。

综合来看,实现 HTTPS 双向认证的老本还是很高的,然而一旦实现,安全系数还是十分高的,不仅仅是绕过审核人员的流量检测,综合来看整个 APP 的网络安全都失去了极大的防护。

四、总结

对于热更新这件事,依据 Apple 的利用标准,基于 JavaScriptCore 的热更新是齐全可行的,但前提是你必须守规矩,不能脱离 Apple 的掌控范畴;然而 App Store 的审核规定又极其不通明,尽管咱们是良民,然而肯定水平上还是要暗藏一下热更新 bundle,躲避不必要的麻烦;暗藏热更新 bundle 咱们能够从信源加密和信道加密两个角度去思考,综合来看就是灵便利用密码学常识,对网络数据进行加密,避免被检测出异样流量,暗藏 bundle 的同时,也爱护了用户的数据安全,升高被攻打的可能性。

五、参考浏览

???? 为什么你的 Charles 会抓包失败?


如果你喜爱我的文章,心愿点赞???? 珍藏 ???? 在看 ???? 三连反对一下!!!谢谢你,这对我真的很重要!

欢送大家关注我的微信公众号:卤蛋实验室,目前专一前端技术,对图形学也有一些渺小钻研。

博客原文:???? 如何暗藏你的热更新 bundle 文件?

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理