JSPatch 原理
JSPatch 能做到通过 JS 调用和改写 OC 方法最根本的原因是 Objective-C 是动态语言,OC 上所有方法的调用/类的生成都通过 Objective-C Runtime 在运行时进行,我们可以通过类名/方法名反射得到相应的类和方法
JSPatch 安全
JSPatch 存在两个安全方面的问题
- 传输安全:JS 脚本可以调用任意 OC 方法,权限非常大,若被中间人攻击替换代码,会造成较大的危害。
- 执行安全:下发的 JS 脚本灵活度大,相当于一次小型更新,若未进行充分测试,可能会出现 crash 等情况对 APP 稳定性造成影响。
传输安全
1. 对称加密
2. HTTPS
3. RSA 校验
RSA校验
服务端计算出脚本文件的 MD5 值,作为这个文件的数字签名。
服务端通过私钥加密第 1 步算出的 MD5 值,得到一个加密后的 MD5 值。
把脚本文件和加密后的 MD5 值一起下发给客户端。
客户端拿到加密后的 MD5 值,通过保存在客户端的公钥解密。
客户端计算脚本文件的 MD5 值。
对比第 4/5 步的两个 MD5 值(分别是客户端和服务端计算出来的 MD5 值),若相等则通过校验。
执行安全
- 回退
- 后台可以提供一个指令让APP不执行JSPatch 的方法
- 测试充分
JSPatch 热更新方案
假设后台版本对应补丁是这样子的
appVersion | patchVersion |
---|---|
1.0.0 | 0.1 |
0.2 | |
0.3 | |
0.4 | |
0.5 |
请求体
Request:
{
appVersion:1.0.0,
bundleVersion:0.3,
...
}
简单一点方法就是将所有的patch下发
Response:
[
...
{
patchVersion:0.1,
patchUrl:<Url>.0.1,
fileMD5:<>, //js文件通过计算出脚本的MD5值,通过RSA加密
...
},
{
patchVersion:0.2,
patchUrl:<Url>.0.2,
fileMD5:<>,
...
},
{
patchVersion:0.3,
patchUrl:<Url>.0.3,
fileMD5:<>,
...
},,
{
patchVersion:0.4,
patchUrl:<Url>.0.4,
fileMD5:<>,
...
},,
{
patchVersion:0.5,
patchUrl:<Url>.0.5,
fileMD5:<>,
...
},
]
发送到前端.然后前端根据本来保存的最后patchVersion的版本.进行选择性的添加.
其实觉得还是后台直接下发缺失的部分比较好.
Response:
[
...
{
patchVersion:0.4,
patchUrl:<Url>.0.4,
fileMD5:<>,
...
},,
{
patchVersion:0.5,
patchUrl:<Url>.0.5,
fileMD5:<>,
...
},
]
最后下载下来的文件,我们通过计算出它的MD5值,我们在通过RSA公钥解密,然后跟下发的MD5进行比对.如果正确,说明没有问题.
不正确,就可能被篡改了,选择重新请求,或者其他方案