android 网络拦截器统一处理请求参数和返回值加解密实现

前言

项目中遇到参数加密和返回结果加密的业务

这里写一下实现 一来加深记忆 二来为以后参考铺垫

需求

项目在开发中涉及到 登陆 发验证码 认证 等前期准备接口

这些接口需要单独处理 比如不加密 或者有其他的业务需求

剩下的是登陆成功以后的业务需求接口 针对入参和返回值做了RSA AES加密

需求大概是这样 下面看下代码实现逻辑

实现

在网络框架的配置类里添加加密拦截器

java 复制代码
 HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory();
        OkHttpClient.Builder mOkHttpBuilder = new OkHttpClient.Builder()
                .connectTimeout(CONN_TIME_OUT, TimeUnit.SECONDS)
                .readTimeout(READ_TIME_OUT, TimeUnit.SECONDS)
                .writeTimeout(WRITE_TIME_OUT, TimeUnit.SECONDS)
                .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
                .addInterceptor(new EncryptionInterceptor()) //加密拦截器 统一处理

解析

我的业务场景是 前期的 登陆 发验证码 认证 接口不需要做加密

所以我需要在加密拦截器前期做单独处理

java 复制代码
 		 //认证接口不处理加密需求
        if (url.encodedPath().equals("xxx/auth")) {
            return chain.proceed(request);
        }
		
		//登陆和验证码都是get接口所以在这里统一拦截 
        if (method.equals("get") || method.equals("delete")) {
            return chain.proceed(request);
        }

处理完特殊业务场景 就剩统一的post接口 参数统一封装成body

java 复制代码
 		 //请求接口请求参数
        String param = InterceptorUtils.bodyToString(request);

        //获取加密的key
        String aesKey = Hawk.get(AppCode.AES_EKY);
        String encryptData = AESUtils.encrypt(param, aesKey);

        //拿到加密后的json字符串
        String json = new Gson().toJson(new JsonRequest(encryptData));
        RequestBody body = RequestBody.create(request.body().contentType(), json);
        request = request.newBuilder().post(body).build();
        Response response = chain.proceed(request);

下图是加密后的参入 统一用data作为加密key-valuekey用于后端解析

再来看一下返回值解密的代码实现 这里有2个点需要注意一下

对于后端返回的类型 无非是对象Object或者数组Array 2种情况 统一封装

先来看一下返回的加密格式

json 复制代码
 {
    	"code":20000,
    	"data":"N1bBAjZ4m6PGGWJmu53PzSOcyjjUL0Jo3UITcEgmxY
    	    	WcnBZSXKXRK81bS65JVoB8ouAuBLSSQvzVxHAc
    			/pRbdUentgpppoe8wfhKvLuVu9LhVPK9y6I9/rf5nNm4h0+R62ubdUNINLsi6tl+j
				/Gn/gMPAzIoEFtVyQMQvHJ1sH4uh4as0Tnxu51aEknNc8Pm",
    	"errorId":"",
    	"message":"操作成功"
    }

上图中,data是我们的业务返回数据 它可能是Array也可能是Object
encryptData 加密字符串

java 复制代码
	//说明是数组
   if (encryptData != null && encryptData.startsWith("[")) {
            JSONArray jsonArray = JSONArray.parseArray(encryptData);
            decryptObj.setData(jsonArray);
   } else if (encryptData != null && encryptData.startsWith("{")) {
               //说明是对象
            JSONObject jsonObject = JSONObject.parseObject(encryptData);
            decryptObj.setData(jsonObject);
      }

EncryptionInterceptor 实现

java 复制代码
public class EncryptionInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        okhttp3.HttpUrl url = request.url();
        String method = request.method().toLowerCase().trim();

        //认证接口不处理加密需求
        if (url.encodedPath().equals("/isp/app/worker/auth")) {
            return chain.proceed(request);
        }

        if (method.equals("get") || method.equals("delete")) {
            return chain.proceed(request);
        }
        //请求接口请求参数
        String param = InterceptorUtils.bodyToString(request);

        //获取加密的key
        String aesKey = Hawk.get(AppCode.AES_EKY);
        String encryptData = AESUtils.encrypt(param, aesKey);

        //拿到加密后的json字符串
        String json = new Gson().toJson(new JsonRequest(encryptData));
        RequestBody body = RequestBody.create(request.body().contentType(), json);
        request = request.newBuilder().post(body).build();
        Response response = chain.proceed(request);
        return Decrypt(response);
    }


    /**
     * 返回值解密
     * @param response 返回值
     * @return response
     */
    private Response Decrypt(Response response) {
        try {
            Response.Builder builder = response.newBuilder();
            Response clone = builder.build();

            //成功 判断是否等于200
            if (clone.code() != 200) {
                return response;
            }
            ResponseBody body = clone.body();
            if (body != null) {
                MediaType mediaType = body.contentType();
                if (mediaType != null) {
                    if (InterceptorUtils.isText(mediaType)) {
                        String aesKey = Hawk.get(AppCode.AES_EKY);
                        BaseResult result = new 
                        Gson().fromJson(body.string(),BaseResult.class);
                        String encryptData = 
                        AESUtils.decrypt(result.getData().toString(), aesKey);
                        ALog.e("解密返回数据 ->" + encryptData);

                        BaseResult decryptObj = new BaseResult();
                        decryptObj.setCode(result.getCode());
                        decryptObj.setErrorId(result.getErrorId());
                        decryptObj.setMessage(result.getMessage());
                        //说明是数组
                        if (encryptData != null && encryptData.startsWith("[")) {
                            JSONArray jsonArray = JSONArray.parseArray(encryptData);
                            decryptObj.setData(jsonArray);
                        } else if (encryptData != null && encryptData.startsWith("{")) {
                            //说明是对象
                            JSONObject jsonObject = JSONObject.parseObject(encryptData);
                            decryptObj.setData(jsonObject);
                        }
                        String strJson = new Gson().toJson(decryptObj);
                        body = ResponseBody.create(mediaType, strJson);
                        return response.newBuilder().body(body).build();
                    }
                }
            }
        } catch (Exception e) {
            ALog.e("解密错误:" + e.getMessage());
        }

        return response;
    }
}

有什么问题欢迎交流~

相关推荐
EasyDSS22 分钟前
视频监控从安装到优化的技术指南,视频汇聚系统EasyCVR智能安防系统构建之道
大数据·网络·网络协议·音视频
rufeike28 分钟前
UDP协议理解
网络·网络协议·udp
似霰1 小时前
安卓adb shell串口基础指令
android·adb
江理不变情1 小时前
海思ISP调试记录
网络·接口隔离原则
世界尽头与你2 小时前
【安全扫描器原理】网络扫描算法
网络·安全
GKoSon2 小时前
加入RPC shell指令 温箱长时间监控
网络·网络协议·rpc
fatiaozhang95273 小时前
中兴云电脑W102D_晶晨S905X2_2+16G_mt7661无线_安卓9.0_线刷固件包
android·adb·电视盒子·魔百盒刷机·魔百盒固件
hgdlip3 小时前
关闭IP属地显示会影响账号的正常使用吗
网络·网络协议·tcp/ip·ip属地
Zz_waiting.4 小时前
网络原理 - 7(TCP - 4)
网络·网络协议·tcp/ip
RECRUITGUY4 小时前
用交换机连接两台电脑,电脑A读取/写电脑B的数据
服务器·网络·负载均衡