Android中对接口进行统一加密

在之前的博客中我们介绍了 加密方案的选择Android中加解密需要注意的地方

本篇博客我们主要来看一下Android结合Retrofit进行加解密时的注意事项。

在开发过程中,接口是很多的,我们不可能分别对每个接口的请求数据都进行加密,这样写起来以及后期维护是非常麻烦的,所以,肯定要是统一处理的
还有我们常用的GetPostDeletePut请求他们的请求数据存放位置是不一样的,所以,我们需要对不同的请求方式做处理。
上传文件时,一般是不需要加密的,还有通过Retrofit请求第三方接口时也是不需要加密的,这些我们都需要考虑到。

目前来讲,我们最常使用的网络请求框架就是Retrofit了,Retrofit实际上就是对OkHttp的封装,网上的一些博客对加解密的处理是在转换器中处理的,实际上我认为这种方式并不好,首先我们来看一下GsonConverterFactory的源码.
Android结合Retrofit实现统一加解密处理(Get、Post、Delete、Put)_第1张图片
看过源码你会发现,转换器只能对响应体和请求体进行处理,解密的时候还好说,加密的时候如果你使用的是Get或者Delete这中请求方式时,转换器是不好进行处理的。所以,关于Retrofit的统一加解密还是建议在拦截器中进行处理。

下面我们来总结一下注意事项:

  • 加解密要统一进行处理,方便维护
  • 加密时要对不同的加密方式进行不同的加密处理
  • 第三方接口,不加密
  • 上传时不加密

Retrofit 统一加密拦截器

拦截器对请求数据加密流程

  1. 获取请求的数据
  2. 对请求数据进行加密
  3. 根据不同的请求方式构造新的request

由于加密的相关逻辑需要跟后台商量,下面代码主要是看实现逻辑和注意事项,具体加密方法根据自身情况进行修改。
加密方案的选择可以看博客开始给的连接去选择。

/** * @description: 对请求数据进行加密处理 * @author : yzq * @date   : 2019/3/16 * @time   : 16:37 * */class RequestEncryptInterceptor : Interceptor {    override fun intercept(chain: Interceptor.Chain): Response {        var request = chain.request()        var charset = Charset.forName("UTF-8")        val method = request.method().toLowerCase().trim()        val url = request.url()        /*本次请求的接口地址*/        val apiPath = "${url.scheme()}://${url.host()}:${url.port()}${url.encodedPath()}".trim()        /*服务端的接口地址*/        val serverPath = "${url.scheme()}://${url.host()}/".trim()        /*如果请求的不是服务端的接口,不加密*/        if (!serverPath.startsWith(ServerConstants.getServerUrl())) {            return chain.proceed(request)        }        /*如果请求方式是Get或者Delete,此时请求数据是拼接在请求地址后面的*/        if (method.equals("get") || method.equals("delete")) {            /*如果有请求数据 则加密*/            if (url.encodedQuery() != null) {                try {                    val queryparamNames = request.url().encodedQuery()                    val encryptqueryparamNames=“这里调用加密的方法,自行修改”             //拼接加密后的url,参数字段自己跟后台商量,这里我用param,后台拿到数据先对param进行解密,解密后的数据就是请求的数据                    val newUrl = "$apiPath?param=$encryptqueryparamNames"                    //构建新的请求                    request = request.newBuilder().url(newUrl ).build()                } catch (e: Exception) {                    e.printStackTrace()                    return chain.proceed(request)                }            }        } else {        //不是Get和Delete请求时,则请求数据在请求体中            val requestBody = request.body()            /*判断请求体是否为空  不为空则执行以下操作*/            if (requestBody != null) {                val contentType = requestBody.contentType()                if (contentType != null) {                    charset = contentType.charset(charset)                    /*如果是二进制上传  则不进行加密*/                    if (contentType.type().toLowerCase().equals("multipart")) {                                             return chain.proceed(request)                    }                }                /*获取请求的数据*/                try {                    val buffer = Buffer()                    requestBody.writeTo(buffer)                    val requestData = URLDecoder.decode(buffer.readString(charset).trim(), "utf-8")                 val encryptData=“这里调用加密的方法,自行修改”                    /*构建新的请求体*/                    val newRequestBody = RequestBody.create(contentType, encryptData)                    /*构建新的requestBuilder*/                    val newRequestBuilder = request.newBuilder()                    //根据请求方式构建相应的请求                    when (method) {                        "post" -> newRequestBuilder.post(newRequestBody)                        "put" -> newRequestBuilder.put(newRequestBody)                    }                    request = newRequestBuilder.build()                } catch (e: Exception) {                    LogUtils.e("加密异常====》${e}")                    return chain.proceed(request)                }            }        }        return chain.proceed(request)    }}

好了,加密拦截器基本就是这样


Retrofit 统一解密拦截器

解密就简单跟多了,直接处理相应体即可,下面是参考代码

/** * @description: 对响应数据进行解密 * @author : yzq * @date   : 2019/3/20 * @time   : 16:13 * */class ResponseDecryptInterceptor : Interceptor {    override fun intercept(chain: Interceptor.Chain): Response {        val request = chain.request()        var response = chain.proceed(request)        if (response.isSuccessful) {            val responseBody = response.body()            if (esponseBody != null) {                /*开始解密*/                try {                    val source = responseBody.source()                    source.request(java.lang.Long.MAX_VALUE)                    val buffer = source.buffer()                    var charset = Charset.forName("UTF-8")                    val contentType = responseBody.contentType()                    if (contentType != null) {                        charset = contentType.charset(charset)                    }                    val bodyString = buffer.clone().readString(charset)                            val responseData = “这里调解密的方法”                                      /*将解密后的明文返回*/                    val newResponseBody = ResponseBody.create(contentType, responseData.trim())                    response = response.newBuilder().body(newResponseBody).build()                } catch (e: Exception) {                    /*异常说明解密失败 信息被篡改 直接返回即可 */                    LogUtils.e("解密异常====》${e}")                    return response                }            } else {                LogUtils.i("响应体为空")            }        }        return response    }}

好了,解密拦截器就完成了。


加解密拦截器写好之后添加到okHttp中即可。

        val okHttpBuilder = OkHttpClient.Builder()            .addInterceptor(RequestHeadersInterceptor())            .addInterceptor(RequestEncryptInterceptor())            .addInterceptor(initLogInterceptor())            .addInterceptor(ResponseDecryptInterceptor())            .build()

然后就可以和后台进行联调测试了。


如果你觉得本文对你有帮助,麻烦动动手指顶一下,算是对本文的一个认可,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!

更多相关文章

  1. Android Studio 基础 之 一键快速实现一个类的 构造函数、getter
  2. Android Studio酷炫插件(一)——自动化快速实现Parcelable接口序列
  3. Android中的UID和PID意义,及查看方式
  4. Android绘图机制(三)——自定义View的实现方式以及半弧圆新控件
  5. 曝Android机冷冻后变"傻" 加密数据随意访问

随机推荐

  1. [Android] 基于 Linux 命令行构建 Androi
  2. Android 4层框架
  3. Android(安卓)打造RxBus2.x的全面详解
  4. 【Monkey】Android(安卓)Monkey autotest
  5. android中的文本框
  6. android:padding和android:margin的区别
  7. Handler&Looper
  8. Android 创建服务器 NanoHttpd
  9. 关于Android菜单上的记录
  10. android仿今日头条App、多种漂亮加载效果