Retrofit/Okhttp API接口加固技术实践(上)

时间:2021-08-01 07:54:28

写这篇文章,我纠结了很久,到底是属于app安全系列,还是属于Retrofit系列,最终我还是选择了将本篇文章归类到Retrofit下。

Retrofit/Okhttp API接口加固技术实践(上)

对于retrofit安全相关的刚开始就写了一篇《Retrofit 2.0 超能实践(一),okHttp完美支持Https传输》(, 文章介绍了怎么使用Retrofit,并且在遇到okhttps的使用方式,但对于加密我们还是无法了解太多,对于安全性要求很高的接口场景还是无法满足,今天就来介绍下对普通api参数的加密!

APP基本安全的文章以前撸了一篇App安全(一) Android防止升级过程被劫持和换包,后续没有再继续跟进,今年会加重安全这块的文章。 主要说下支付宝为代表的用的安全策略技术,本篇介绍下API加固的常用技术。常用的模式是加密-认证身份-鉴别权限-解密过程。

Retrofit/Okhttp API接口加固技术实践(上)

Api加固除了本身支持Https,还会额外进行上图中一系列的加密策略,自定义对Resquest/Response Data进行加密,对url加密,甚至对request进行校验等。如果你加入RxJava操作符做一系列的加密流程,那将是锦上添花。解密过程也直接使用RxJava ,map操作符转换解密后返回给业务层,RxJava之前也介绍过好几篇,这里不再安利。

加固API主要由四种方案:

使用Https

URL加密

参数加密

加入权限

时效验证

数字签名

Https

以前写过一篇文章可以参考 :Retrofit 2.0 超能实践(一),完美支持加密Https传输

URL加密

只针对普通get请求,不针对post表单提交及ajax方式
策略:对于暴露在浏览器地址栏中的地址进行加密,如一个属性为name=tamic,
假设对tamic加密后为kadfxarf24saa:
假设真实值在这段字符中间,那么我们可以对前三位进行随机,后三位随机,
再对真实的tamic进行加密转换(base64都行),然后再来个倒序,那么剩下的数字我们可以获取当前时间追加,最后再进行md5都行,这样普通的用户无法感知具体路径真实值是什么,甚至一般黑客都无法轻易解析具体内容,服务端拿到具体值的策略也是一样

只要按约定的好的算法进行解码就行了。这样不仅能防止恶意程序请求我们的服务端。而且还能对具体的参数地址进行加密。

参数加密

参数加密一般针对表单中的字段和值进行加密,防止中途第三方进行窥探和篡改。一般我们可以用okhttp的Interceptor 进行处理。 可以在发动报文前,对参数进行加密转码。

案列:

public class EncryptionInterceptor implements Interceptor { private static final String TAG = EncryptionInterceptor.class.getSimpleName(); private static final boolean DEBUG = true; @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); RequestBody oldBody = request.body(); Buffer buffer = new Buffer(); oldBody.writeTo(buffer); String strOldBody = buffer.readUtf8(); MediaType mediaType = MediaType.parse("text/plain; charset=utf-8"); String strNewBody = CodeMachine.encrypt(strOldBody); RequestBody body = RequestBody.create(mediaType, strNewBody); request = request.newBuilder().header("Content-Type", body.contentType().toString()).header("Content-Length", String.valueOf(body.contentLength())).method(request.method(), body).build(); return chain.proceed(request); }}

加密算法自己和服务端约定即可

private static String encrypt(String ){ //your code }

add到client即可

client = new OkHttpClient.Builder() .addNetworkInterceptor(new EncryptionInterceptor()).build(); retrofit = new Retrofit.Builder().client(client).build();

服务端代码也是拿到具体参数进行同步的加密算法来进行反解密。

加入权限

权限控制也是对接口加密的一种业务层策略,比如一个电商APP,有商户,有用户,,有中间物流商,还有中间服务商,那么同一个获取商品信息的权限不同的,商家有修改商品信息的权限,用户只能浏览查看的功能,物流商可以有指定物流渠道权限,中间服务商可以拥有协调监督功能,如归有涉及假冒,法律的可以强制下架改商品,那么是同样一个getProductInfo接口 却又不同的信息,那么这个接口定义的时候,服务端和移动端就已经商讨好了协议,赋予不同角色权限.

public enum Permission { User, Shop, Courier, Platform }

如上展示了四种角色控制,不同角色Server返回的数据Module也是不同的。 遇到三方恶意攻击,服务端确定并客户端发来的权限并不是我们固定的角色,那么服务端也将视这次请求为无效的。

时效验证