Android OkhttpRetrofit网络请求加解密实现方案

Android OkhttpRetrofit网络请求加解密实现方案,第1张

比较安全的方案应该是AES+RSA的加密方式。具体如下图所示。

为什么要这样做呢?

1、RSA是非对称加密,公钥和私钥分开,且公钥可以公开,很适合网络数据传输场景。但RSA加密比较慢,据说比AES慢100倍,且对加密的数据长度也有限制。

2、AES是对称加密,加密速度快,安全性高,但密钥的保存是个问题,在网络数据传输的场景就很容易由于密钥泄露造成安全隐患

3、所以,AES+RSA结合才更好,AES加密数据,且密钥随机生成,RSA用对方(服务器)的公钥加密随机生成的AES密钥。传输时要把密文,加密的AES密钥和自己的公钥传给对方(服务器)。对方(服务器)接到数据后,用自己的私钥解密AES密钥,再拿AES密钥解密数据得到明文。这样就综合了两种加密体系的优点。

4、除上面说的外,还可以加签名,即对传输的数据(加密前)先做个哈希,然后用自己的RSA私钥对哈希签名(对方拿到自己的公钥可以验签),这样可以验证传输内容有没有被修改过。

就java来说,加密的输入和输出都是字节数组类型的,也就是二进制数据,网络传输或本地保存都需要重新编码为字符串。推荐使用Base64。Android 有自带的Base64实现,flag要选Base64NO_WRAP,不然末尾会有换行影响服务端解码。

Android中Base64加密

总而言之,这些不同语言都有实现库,调用即可,关键是参数要一致,具体还需要和后台联调一下。

rsa加解密的内容超长的问题解决

现在说到网络框架,应该毫无疑问是Retrofit了。上面说的加密方案说到底还是要在网络请求框架内加上,怎么做入侵最小,怎么做最方便才是重点。

1、坑定不能直接在接口调用层做加密,加参数,这样每个接口都要修改,这是不可能的。

2、ConverterFactory处理,这也是网上可以搜到的很多文章的写法,但我觉得还是有入侵。而且有点麻烦。

3、OkHttp添加拦截器,这种方法入侵最小(可以说没有),实现呢也非常优雅。

下面的实现,网上也找不到多少可以参考的文章,但不得不说,OkHttp的封装和设计真的很好用,所见即所得。看下源码,就知道该怎么用了,连文档都不用查。

主要注意点:

0、和接口无关的新加的数据放在请求头里。

1、该close的要close,不然会内存泄漏。

2、新旧Request和Response要区分好,新的要替换旧的去传递或返回。

3、要对responsecode()做处理,只有在和后台约定好的返回码下才走解密的逻辑,具体看自己的需求,不一定都是200。

问题出现的原因是因为Android高版本(Android 60)以上默认使用TLS保护用户信息,详见以下文档:

Transport Layer Security

摘录关键信息如下:

简单地说,在Android高版本对非加密的明文传输有要求,也即默认启用了TLS保护,使得该应用无法进行http网络请求,而https则不会受影响,同样地,如果应用嵌套了webview也会受这限制。

针对这种情况,有以下解决方案:

然后在AnroidManifestxml中的application添加指向该文件的设置项:

android:networkSecurityConfig="@xml/network_security_config"

综合考量,第3种方案个人认为会好点,Cordova配合其使用也很简单:

在configxml文件中,在 <platform name="android"/> 节点内添加配置项即可:

这样Cordova build的时候就会把上面配置合并到AnroidManifestxml中。

业内已有的 WKWebView 请求拦截方案,主要分为如下两种

NSURLProtocol 默认会拦截所有经过 URL Loading System 的请求,因此只要 WKWebView 发出的请求经过 URL Loading System 就可以被拦截。经过我们的尝试,发现 WKWebView 独立于应用进程运行,发出去的请求默认是不会经过 URL Loading System,需要我们额外进行 hook 才能支持,具体的方式可以参考 NSURLProtocol对WKWebView的处理 。

虽然NSURLProtocol可以拦截监听每一个 URL Loading System 中发出 request 请求,记住是URL Loading System中那些类发出的请求,也支持AFNetwoking,UIWebView发出的request,NSURLProtocol都可以拦截和监听。

因为WKWebView 在独立进程里执行网络请求。一旦注册 http(s) scheme 后,网络请求将从 Network Process 发送到 App Process,这样 NSURLProtocol 才能拦截网络请求。

但是在 WebKit2 的设计里使用 MessageQueue 进行进程之间的通信,Network Process 会将请求 encode 成一个 Message,然后通过 IPC(进程间通信) 发送给 App Process。出于性能的原因,encode 的时候 将HTTPBody 和 HTTPBodyStream 这两个字段丢弃掉( )

因此,如果通过 registerSchemeForCustomProtocol 注册了 http(s) scheme, 那么由 WKWebView 发起的所有 http(s)请求都会通过 IPC 传给主进程 NSURLProtocol 处理,导致 post 请求 body 被清空;

说明1 :名目张胆使用私有API,是过不了AppStore审核的,具体使用什么办法,想来你也懂(hun xiao)。

说明2 :一旦打开ATS开关: Allow Arbitrary Loads 选项设置为NO ,通过 registerSchemeForCustomProtocol 注册了 http(s) scheme,WKWebView 发起的所有 http(s) 网络请求将被阻塞(即便将 Allow Arbitrary Loads in Web Content 选项设置为YES );

说明3 :iOS11之后可以通过 WKURLSchemeHandler 去完成对 WKWebView 的请求拦截,不需要再调用私有API解决上述问题了。

WKURLSchemeHandler是iOS11就推出的,用于处理自定义请求的方案,不过并不能处理Http、Https等常规scheme。

WKURLSchemeHandler 负责自定义请求的数据管理,如果需要支持 scheme 为 http 或 https请求的数据管理则需要 hook WKWebView 的 handlesURLScheme: 方法,然后返回NO即可。

调研的结论是: WKURLSchemeHandler 在隔离性、稳定性、一致性上表现优于 NSURLProtocol ,但是想在生产环境投入使用必须要解决 Body 丢失的问题。

总结:

NSURLProtocol

缺点:针对WKWebView流量需要额外使用私有方法,虽然可以通过混淆方式屏蔽关键词但是无法保证日后版本升级仍然适用

WKURLSchemeHandler

缺点:需要针对WKWebView实例设置,WKWebView实例零散的场景不适用

引用文章:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/11669700.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-17
下一篇 2023-05-17

发表评论

登录后才能评论

评论列表(0条)

保存