前言
项目中遇到参数加密和返回结果加密的业务
这里写一下实现 一来加深记忆 二来为以后参考铺垫
需求
项目在开发中涉及到 登陆
发验证码
认证
等前期准备接口
这些接口需要单独处理 比如不加密 或者有其他的业务需求
剩下的是登陆成功以后的业务需求接口 针对入参和返回值做了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-value
的key
用于后端解析
再来看一下返回值解密的代码实现 这里有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;
}
}
有什么问题欢迎交流~