赞
踩
如果你对于网络请求用了https后是否还有必要对参数加密有疑问可以看我上篇的文章:网络安全https 记得耐心看完,下面说问题:
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(),拿到字符串自己解析。
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。