请选择 进入手机版 | 继续访问电脑版

Android Okhttp 拦截器中加密 请求体 (DES加密解密)

[复制链接]
奇奇女 发表于 2021-1-2 11:53:02 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
最近公司为了项目安全  使用了https 所有接口要使用DES 加密 加密 RequestBody 的value值  
心想   这不是很简单吗   直接在拦截器中获取到要上传的数据  然后加密 重新赋值  很简单嘛   但是实践起来  我真的气的想要骂娘  太坑了好吗。。。。无语直接就打到我的脸上
废话不多说  让我重温一下这些坑
第一步  在网络请求类里添加拦截器  
在拦截器里对上传的数据举行利用 
如果是post 请求 取出来request.body(); 循环 取出  encodedValue 加密后 重新再 addEncoded 添加进去 这里要注意 URLDecoder的解码 
如果是get请求 先拿到  request.url() 然后再看这个url中包罗不包罗请求参数  url.encodedQuery() 如果这个不为空的话  就是接下来字符串截取->修改加密->重新拼接 
然后举行网络请求
然后解密 ---->
和背景商量后  背景返回的数据只对 “data” 字段的value举行了加密 好  那我只对“data” 举行解密就好了
获取到 response 对返回的json举行分析  因为背景对“data”举行加密 无疑 data是String范例的  分析解密后 怎么将解密后的data重新安装到json中呢 ?
解密后的data是String范例的   但是原本想要表达的 “data” 该是什么范例呢  不知道什么范例 又该怎么准确的安到实体类里呢  
我被这个“data”困阻了  一直在想 怎么直接去利用json串  我知道这也不是一个绝美精妙的办法  但是我脑容量究竟不大  我以为我能想到管理的办法已经很棒了  substring(0,1);究竟 返回的json也就那么几种 { 、[ 、另有什么都没有的
那不就好办了吗   直接统称两类  jsonArray 和jsonObject 至此  我才终于有了完整的思路 
我猜看到这里各人也到了耐烦的极限了   但是整体的思路  使用的方法  上面已经根本都讲的差不多了  合格的步伐员 应该脑海里也知道该怎么做了    有点凡尔赛那味了
上代码!!!!
 
  1. public class OkhttpInstance {    private static OkHttpClient okHttpClient;    private static Response response;    public static synchronized OkHttpClient createInstance() {        if (okHttpClient == null) {            synchronized (OkhttpInstance.class) {                if (okHttpClient == null) {                    okHttpClient = new OkHttpClient.Builder()                            .connectTimeout(60, TimeUnit.SECONDS)      //设置毗连超时                            .readTimeout(60, TimeUnit.SECONDS)         //设置读超时                            .writeTimeout(60, TimeUnit.SECONDS)        //设置写超时                            .retryOnConnectionFailure(true)            //是否自动重连                            .addInterceptor(interceptor)  //添加拦截器                            .build();                }            }        }        return okHttpClient;    }    private static Interceptor interceptor = new Interceptor() {        @Override        public Response intercept(Chain chain) throws IOException {            Request request = chain.request();            Request.Builder requestBuilder = request.newBuilder();            //post请求加密            if (request.body() instanceof FormBody) {                FormBody.Builder newFormBody = new FormBody.Builder();//创建新表单                FormBody oidFormBody = (FormBody) request.body();//请求表单                //循环取出 request Body 注意FormBody 才会有size属性 FormBody可以满足大部分的请求                for (int i = 0; i < oidFormBody.size(); i++) {                    String str = oidFormBody.encodedValue(i);//value                    String decode = URLDecoder.decode(str);//对value举行URLDecoder解码                    String s = oidFormBody.encodedName(i);//name                    String name = URLDecoder.decode(s);//对name举行URLDecoder解码 很重要 这两个都加上 否则取出请求体的时候有的请求体被URLDecoder编码 背景不知道你传已往的是什么                     String encrypt = DesCipherUtil.encrypt(decode, HDUrl.PAS);//des加密 HDUrl.PAS 是我的暗码 你跟背景商量定什么为暗码                    newFormBody.addEncoded(name.trim(), encrypt.trim());//去空格 相当重要!!都是我踩过的坑                }                requestBuilder.method(request.method(), newFormBody.build());            }            request = requestBuilder.build();//            get请求加密            //还回加密的请求头            HttpUrl url = request.url();            String path = url.encodedPath();//            String query = url.encodedQuery();//请求参数            if (!TextUtils.isEmpty(query)) {                StringBuffer sb = new StringBuffer();                sb.append(HDUrl.DEFAULT).append(path).append("?");//HDUrl.DEFAULT是我的请求地点:https://192.16.2.88 我猜你知道我说的是什么                Set queryList = url.queryParameterNames();                Iterator iterator = queryList.iterator();                for (int i = 0; i < queryList.size(); i++) {                    String queryName = iterator.next();                    sb.append(queryName).append("=");                    String queryKey = url.queryParameter(queryName);                    //对query的key举行加密                    if (TextUtils.isEmpty(queryKey) || null == queryKey || "null".equals(queryKey) || queryKey.length() == 0 || "".equals(queryKey)) {                    } else {                        Log.e("tag", "queryKey-----------" + queryKey);                        sb.append(DesCipherUtil.encrypt(queryKey, HDUrl.PAS));                    }                    if (iterator.hasNext()) {                        sb.append("&");                    }                }                String newUrl = sb.toString();//                举行加密后的get请求链接                Request.Builder url1 = request.newBuilder()                        .url(newUrl);                request = url1.build();            }            response = chain.proceed(request);            byte[] data = response.body().bytes();            String s = new String(data);            MediaType mediaType = response.body().contentType();            try {                Log.e("tag", "s-----------------------" + s);                JSONObject jsonObject = new JSONObject(s);                int code = 0;                if (jsonObject.has("code")) {                    code = jsonObject.getInt("code");                } else {                    code = jsonObject.getInt("errCode");                }                if (code == 200 || code == 0) {//                    当code=200/0时解密                    if (jsonObject.has("data")) {                        String code1 = jsonObject.getString("data");                        String decrypt = DesCipherUtil.decrypt(code1, HDUrl.PAS);                        jsonObject.remove("data");                        jsonObject.put("data", decrypt);                        Gson gson = new Gson();//                        DefaultBean defaultBean = gson.fromJson(s, DefaultBean.class);                        if (decrypt.substring(0, 1).equals("[")) {                            List arrData = gson.fromJson(decrypt, new TypeToken() {                            }.getType());                            defaultBean.setData(arrData);                        } else if (decrypt.substring(0, 1).equals("{")) {                            Object objectData = gson.fromJson(decrypt, Object.class);                            defaultBean.setData(objectData);                        } else {                            defaultBean.setData(decrypt);                        }                        s = new Gson().toJson(defaultBean);                    }                } else if (code == 10100) {                    //就代表token逾期了                    Thread thread = new Thread(new Runnable() {                        @Override                        public void run() {                            Looper.prepare();                            UserInfo userInfo = (UserInfo) ShareprefencesUtils.getBean(App.getApplicationContent(), ShareprefencesUtils.USER_INFO);                            userInfo.setAccess_token("");                            ShareprefencesUtils.putBean(App.getApplicationContent(), ShareprefencesUtils.USER_INFO, userInfo);                            Intent intent = new Intent(App.getApplicationContent(), SelectJoinActivity.class)                                    .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);                            App.getApplicationContent().startActivity(intent);                            Toast.makeText(App.getApplicationContent(), "登录超时请重新登录", Toast.LENGTH_SHORT).show();                            Looper.loop();                        }                    });                    thread.start();                }            } catch (JSONException e) {                e.printStackTrace();            }            return response.newBuilder()                    .body(ResponseBody.create(mediaType, s))                    .build();        }    };    public static synchronized OkHttpClient getInstance() {        return okHttpClient;    }
复制代码
实在已经很容易看懂了  一些东西我就不做表明了   自己悟去吧 下面贴一下DES加密解密类
  1. private DesCipherUtil() {        throw new AssertionError("No DesCipherUtil instances for you!");    }    static {        // add BC provider//        Security.addProvider(new BouncyCastleProvider());    }    /**     * 加密     *      * @param encryptText 需要加密的信息     * @param key 加密密钥     * @return 加密后Base64编码的字符串     */    @SuppressLint("NewApi")    public static String encrypt(String encryptText, String key) {        if (encryptText == null || key == null) {            throw new IllegalArgumentException("encryptText or key must not be null");        }        try {            DESKeySpec desKeySpec = new DESKeySpec(key.getBytes());            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS7Padding", "BC");            cipher.init(Cipher.ENCRYPT_MODE, secretKey);            byte[] bytes = cipher.doFinal(encryptText.getBytes(Charset.forName("UTF-8")));            return Base64.getEncoder().encodeToString(bytes);        } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException | NoSuchPaddingException            | BadPaddingException | NoSuchProviderException | IllegalBlockSizeException e) {            throw new RuntimeException("encrypt failed", e);        }    }    /**     * 解密     *      * @param decryptText 需要解密的信息     * @param key 解密密钥,颠末Base64编码     * @return 解密后的字符串     */    public static  String decrypt(String decryptText, String key) {        if (decryptText == null || key == null) {            throw new IllegalArgumentException("decryptText or key must not be null");        }        try {            DESKeySpec desKeySpec = new DESKeySpec(key.getBytes());            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS7Padding", "BC");            cipher.init(Cipher.DECRYPT_MODE, secretKey);            byte[] bytes = new byte[0];            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {                bytes = cipher.doFinal(Base64.getDecoder().decode(decryptText));            }            return new String(bytes, Charset.forName("UTF-8"));        } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException | NoSuchPaddingException            | BadPaddingException | NoSuchProviderException | IllegalBlockSizeException e) {            throw new RuntimeException("decrypt failed", e);        }    }    public static void main(String[] args) {        }
复制代码
这些都是我实实在在用到项目中的    有问题别质疑   我的代码没有问题   傲娇脸     
 

来源:https://blog.csdn.net/unknown_315/article/details/112007136
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发布主题

专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )