Android HTTP Retrofit 数据加密RSA+AES

1.背景

在不用https的情况下,网络请求需要手动加密,加密的方式有很多,对称加密或者非对称加密,考虑到安全性的前提,非对称加密是必须的,但是如果传输的数据量很大,例如传输一张人脸图片,传输加上服务端解密会比较慢。

所以采取对称加密+非对称加密最佳,以下介绍RSA+AES的加密方式

2.实现方式

Android 持有服务端生成的RSA公钥,数据用随机生成的AES秘钥加密,AES秘钥用RSA公钥加密,加密后的AES秘钥通过请求头的方式传输给服务端,服务端返回的数据再用AES解密,请求完成。因为AES每次请求都是重新生成,保证了安全性,没有服务端RSA私钥就算拦截到了请求也解不开。

3.代码

  • Retrofit中添加拦截器
OkHttpClient.Builder okBuilder = new OkHttpClient.Builder().addInterceptor(new DataEncryptInterceptor());

 retrofit = new Retrofit.Builder().client(okBuilder.build()).build();
  • 拦截器代码实现
    public class DataEncryptInterceptor implements Interceptor {


        @Override
        public Response intercept(Chain chain) throws IOException {
            //请求
            Request request = chain.request();
            MediaType mediaType = MediaType.parse("text/plain; charset=utf-8");
            //随机生成AES秘钥
            String aesKey = AESUtil.getAESKey();
            try {
                //获取未加密数据
                RequestBody oldRequestBody = request.body();
                Buffer requestBuffer = new Buffer();
                oldRequestBody.writeTo(requestBuffer);
                String oldBodyStr = requestBuffer.readUtf8();
                requestBuffer.close();

                //未加密数据用AES秘钥加密
                String  newBodyStr= EncryptionManager.getInstance().publicEncryptClient(oldBodyStr);
                //AES秘钥用服务端RSA公钥加密
                String key= EncryptionManager.getInstance().publicEncrypt(aesKey);
                //构成新的request 并通过请求头发送加密后的AES秘钥
                Headers headers = request.headers();
                RequestBody newBody = RequestBody.create(mediaType, newBodyStr);
                //构造新的request
                request = request.newBuilder()
                        .headers(headers)
                        .addHeader("Device-Key", key)
                        .method(request.method(), newBody)
                        .build();
            }catch (Exception e){

            }
            //响应
            Response response = chain.proceed(request);
            if (response.code() == 200) {
                try {
                    //获取加密的响应数据
                    ResponseBody oldResponseBody = response.body();
                    String oldResponseBodyStr = oldResponseBody.string();
                    //加密的响应数据用AES秘钥解密
                    String newResponseBodyStr="";
                    if (!TextUtils.isEmpty(oldResponseBodyStr)){
                        newResponseBodyStr = AESUtil.aesDecrypt(oldResponseBodyStr,aesKey);
                    }
                    oldResponseBody.close();
                    //构造新的response
                    ResponseBody newResponseBody = ResponseBody.create(mediaType, newResponseBodyStr);
                    response = response.newBuilder().body(newResponseBody).build();
                }catch (Exception e){
                    LogUtils.d("RetrofitLog","e"+e.getMessage());
                }finally {
                    response.close();
                }
            }
            //返回
            return response;
        }
    }

4.其他

AES和RSA的秘钥生成和加解密就不写了,网上一大堆

你可能感兴趣的:(Android HTTP Retrofit 数据加密RSA+AES)