okhttp post请求 header post参数加密遇到的两个问题

如果你对于网络请求用了https后是否还有必要对参数加密有疑问可以看我上篇的文章:网络安全https 记得耐心看完,下面说问题:

  1. Caused by: java.lang.IllegalArgumentException: Unexpected char 0x0a 一开始以为是okhttp框架对特殊字符做了现在,网上其他文章说的是对中文字符,我想我这也没中文啊,但还是全部换成原生试了一下,果然,还是一样报错,坑爹的网友啊,哈哈!
    下面是测试用例demo的代码
package com.tcssj.mbjmb;

import android.util.Base64;
import android.view.View;

import java.nio.charset.StandardCharsets;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESUtil2 {
    public static byte[] base64ToDecode(String str) {
        byte[] byteStr = Base64.decode(str, Base64.DEFAULT);
        return byteStr;
    }

    public static String encode(byte[] key) {
        return Base64.encodeToString(key, Base64.NO_WRAP);
    }

    /**
     * 加密
     *
     * @param content 需要加密的内容
     * @param key     加密密码
     * @return
     */
    public static String encrypt(String content, String key) {
        return encrypt(content,key.getBytes());
    }

    public static String encrypt(String content, byte[] key) {
        try {
            //构造密钥
            SecretKeySpec skey = new SecretKeySpec(key, "utf-8");
            //创建初始向量iv用于指定密钥偏移量(可自行指定但必须为128位),因为AES是分组加密,下一组的iv就用上一组加密的密文来充当
            IvParameterSpec iv = new IvParameterSpec(key, 0, 16);
            //创建AES加密器
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] byteContent = content.getBytes(StandardCharsets.UTF_8);
            //使用加密器的加密模式
            cipher.init(Cipher.ENCRYPT_MODE, skey, iv);
            // 加密
            byte[] result = cipher.doFinal(byteContent);
            //使用BASE64对加密后的二进制数组进行编码
            return encode(result);
        } catch (Exception e) {
            e.printStackTrace();
            return content;
        }
    }

    /**
     * 解密
     * @param content
     * @param key
     * @return
     */
    public static String decrypt(String content,  byte[] key) {
        try {

            SecretKeySpec skey = new SecretKeySpec(key, "utf-8");
            IvParameterSpec iv = new IvParameterSpec(key, 0, 16);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            //解密时使用加密器的解密模式
            // 初始化
            cipher.init(Cipher.DECRYPT_MODE, skey, iv);
            byte[] result = cipher.doFinal(base64ToDecode(content));
            // 解密
            return new String(result);
        } catch (Exception e) {
            return content;
        }
    }
}

package com.tcssj.mbjmb

import android.os.Bundle
import android.os.Handler
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.tcssj.mbjmb.ui.theme.MbjmbTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import okhttp3.Headers
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import org.json.JSONObject

class MainActivity : ComponentActivity() ,test {
    private  val TAG = "MainActivity"
    lateinit var  text:String
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
   runBlocking(Dispatchers.IO) {
       val okHttpClient=OkHttpClient()
//        val build=okHttpClient.newBuilder()
       val jsonpost=JSONObject()
       jsonpost.put("type","text")
       jsonpost.put("mobile","81991419936")
       val body=RequestBody.create(MediaType.parse("application/json;charset=utf-8"),AESUtil2.encrypt(jsonpost.toString(),AESUtil2.base64ToDecode("allWUzg1eFJ3ekpNQklUeQ==")))

       val json=JSONObject()
       json.put("sourceChannel","Orange")
       json.put("packageName","com.tcssj.mbjmb")
       json.put("adid","")
       json.put("version","12.0.0")
       json.put("uuId","")
       json.put("userId","")
       val request= Request.Builder().url("http://47.101.194.189:10018/auth/v3.1/user/sendVerifiyCode")
           .header("HCFQ",AESUtil2.encrypt(json.toString(), "xDBrgJdnnY2w1Do7Ik6otonXQRgQyt46"))
           .header("packageName","mbjmb")
           .post(body)
           .build()

       val response= okHttpClient.newCall(request).execute()
       response.toString()
       text=AESUtil2.decrypt(response.body().string(), AESUtil2.base64ToDecode("allWUzg1eFJ3ekpNQklUeQ=="))
       Log.i(TAG, "onCreate: "+AESUtil2.decrypt(text, AESUtil2.base64ToDecode("allWUzg1eFJ3ekpNQklUeQ==")))
   }
        setContent {
            MbjmbTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Greeting(name =text)
                }
            }
        }



    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "$name!",
        modifier = modifier
    )
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    MbjmbTheme {
        Greeting("Android")
    }
}

第一个问题的原因就是我们参数进行加密后有换行符号\n,怎么解决呢?如下图,划线的部分你如果是用的Default,那就会报第一个错误,你需要使用NO_WRAP 不生成换行符的。
在这里插入图片描述
第二个坑就是返回的也是加密后的乱码,你需要拿回来解密的,那你下图中就不能使用body.toString() 方法,要用String()方法。(我是怎么发现的,我用apifox 工具(如果你接口调试还没使用上,拿走不谢,还是要用这么个工具,不然你来来回回启动app调试接口效率很低,但你会懒的使用,抗拒学新的,人吗,天性,但你要克服)调试接口的时候,发现工具和android里面的返回结果不一致)
在这里插入图片描述
因为看下图,如果你用了toString 方法 message当时空的,整个是空的框架,加密的内容okhttp无法转换成它的结构,那你就要用string(),拿到字符串自己解析。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/111204.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python小试牛刀:GUI(图形界面)实现计算器界面

Python GUI 是指 Python 图形用户界面库,它们可以帮助开发者创建在计算机上运行的图形用户界面(GUI)。下面是一些常用的 Python GUI 库: Tkinter: Tkinter 是 Python 的标准 GUI 库,它是一个开源的、跨平台…

【C++】多态 ⑧ ( 验证指向 虚函数表 的 vptr 指针 | 对比定义了虚函数的类和没有定义虚函数类的大小 )

文章目录 一、验证指向 虚函数表 的 vptr 指针 是否存在1、虚函数表与 vptr 指针由来2、虚函数类与普通函数类对比 - 多出了 vptr 指针的大小 对比 定义了 虚函数 的类 与 没有定义虚函数的类 的大小 , 其它成员都相同 , 定义了虚函数的类多出了 4 字节 , 多出的 4 字节就是 vp…

Windows11无法打开Photoshop CC 2017问题解决

情况描述: Windows11上,双击Photoshop CC 2017没反应 解决办法: 此时需要启动Windows的“事件查看器”来确认问题出在哪里。可以直接通过开始菜单搜索启动,也可以通过右键点击“此电脑”->“管理”,然后找到事件查…

《微聊》JMeter性能测试报告

文章目录 准备工作JMeter准备工作本地配置代理 测试规划测试方向预期方向异常处理 压力测试录制注册功能压力注册功能压力脚本录制录制功能压力测试脚本完善注册功能压力测试结果 登录功能压力录制登录功能压力测试脚本构造压力测试数据完善登录功能性能测试脚本登录功能压力测…

Servlet的继承树,生命周期和线程不安全

1、Servlet 继承树 3)Servlet的继承树 - Servlet接口public interface Servlet{public void init(config);public void service(request,response);public void destroy();} - GenericServlet抽象类public abstract class GenericServlet implements Servlet{实现了init方法和d…

android查漏补缺(8)Binder framework架构和调用方法

1.Binder简介 Binder是android系统中实现进程间通信的主要组件,包括各种AMS,PMS,SMS等服务和APK的通信都是通过binder实现。但是调用过PMS的同学肯定会有疑问,既然是进程通信,怎么没有消息的发送和接收,为什么调用不同进程的服务的…

出海数字化,国产CRM如何支撑?纷享销客这样思考

2023年,疫情阴霾逐渐消散,企业全球化扩张的齿轮重新加速。以科技企业、高端制造业为代表的优秀企业引领中国企业出海浪潮,外资企业在华的经营活跃度也在提升。 无论是”外资在华经营“还是”中资出海“,这些具备全球化理想的企业…

宝塔安装mongodb插件失败的解决办法

安装时始终不成功。 进入控制台进行安装 /www/server/php/71# pecl install mongodb WARNING: channel "pecl.php.net" has updated its protocols, use "pecl channel-update pecl.php.net" to update pecl/mongodb requires PHP (version > 7.2.0, …

Dataworks API:调取 MC 项目下所有表单

文章目录 前言Dataworks API 文档解读GetMetaDBTableList 接口文档 API 调试在线调试本地调试运行环境账密问题请求数据进一步处理 小结 前言 最近,我需要对公司的数据资产进行梳理,这其中便包括了Dataworks各个项目下的表单。这些表单,作为…

Android 处理多个TextView, 文案过长时前面文本省略的问题

遇到显示多个TextView,文案过短时,这几个TextView跟随显示,文案过程时,前面TextView省略,后个的TextView全显示。效果如下: 用ConstraintLayout 没有得到解决,采用 RelativeLayout 解决 代码如…

按相同时间切割长视频

需求 将一段1小时的.mkv视频,按每5分钟切割,并转成.mp4 工具 格式工程 x64 5.15,下载 这真是个好工具,考虑过PR,无意间发现这软件很强大 实现步骤 第一步:选择视频,导出MP4,添…

libcurl库的网页爬虫程序

示例代码&#xff1a; #include <curl/curl.h> #include <iostream> ​ int main() {CURL *curl;CURLcode res; ​curl_global_init(CURL_GLOBAL_DEFAULT); ​curl curl_easy_init();if(curl) {curl_easy_setopt(curl, CURLOPT_URL, "/");curl_easy_se…

CSS与基本选择器

<div class"c1" id"d1"></div> CSS基本知识 什么是css&#xff1a;CSS&#xff08;Cascading Style Sheet&#xff0c;层叠样式表)定义如何显示HTML元素。 当浏览器读到一个样式表&#xff0c;他就会按照这个样式l来进行渲染。其实就是让HT…

雷迪管线探测仪故障定位仪维修RD8100

英国雷迪管线探测仪常见维修型号&#xff1a;RD4000&#xff1b;RD7000&#xff1b;RD8000&#xff1b;RD8100等。 应该范围&#xff1a;是目前探测煤气、电力、自来水、排水等各类地下管线的仪器之一。 雷迪管线探测仪具有直连线特点&#xff1a;用直连线可以将发射机直接与需…

基于Canal同步MySQL数据到Elasticsearch

基于Canal同步MySQL数据到Elasticsearch 基于 canal 同步 mysql 的数据到 elasticsearch 中。 1、canal-server 相关软件的安装请参考&#xff1a;《Canal实现数据同步》 1.1 pom依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmln…

Android图形系统之HWComposer、ComposerHal、ComposerImpl、Composer、Hwc2::Composer实例总结(十四)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

利用远程IO模块,轻松驾驭食品包装生产的自动化

常见的自动化包装系统&#xff0c;它的核心部分通常由一系列高端设备组成&#xff0c;包括自动开箱机、自动封箱机、自动捆扎机、装箱机器人、码垛机器人等。这些设备协同工作&#xff0c;形成一条高效运转的生产线&#xff0c;从开箱到装箱&#xff0c;再到码垛&#xff0c;每…

多测师肖sir_高级金牌讲师_性能测试之badboy录制脚本02

性能测试之badboy录制脚本 一、下载安装包&#xff0c;点击安装 二、点击我同意 三、选择路径&#xff0c;点击install 打开以下界面&#xff0c;表示安装成功 第二步&#xff1a;录制流程 界面视图&#xff0c;模拟浏览器&#xff0c;能够进行操作 需要录制脚本的URL 点…

MLF - 麻辣粉

MLF全称中期借贷便利&#xff08;Medium-term lending Facility&#xff09;,理解为央行向商业银行、政策银行发放的贷款&#xff0c;但需要符合一定要求才可向央行申请。银行通过MLF向央行借款的时候&#xff0c;需要提供担保品。一般为国债、央行票据、政策性金融债、地方债、…

C++设计模式_19_Memento 备忘录(理解,目前多使用序列化方案来实现)

Memento 备忘录模式也属于“状态变化”模式&#xff0c;它是一个小模式&#xff0c;在今天来看有些过时&#xff0c;当今已经很少使用当前模式实现需求&#xff0c;思想却不变&#xff08;信息隐藏&#xff09;&#xff0c;目前多使用序列化方案来实现。本系列所介绍的模式&…