写点什么

JAVA 微信小程序 解密 用户信息 encryptedData

作者:Java高工P7
  • 2021 年 11 月 11 日
  • 本文字数:2699 字

    阅读完需:约 9 分钟

byte[] ivByte = Base64.decodeBase64(iv);


try {


// 如果密钥不足 16 位,那么就补足. 这个 if 中的内容很重要


int base = 16;


if (keyByte.length % base != 0) {


int groups = keyByte.length / base


  • (keyByte.length % base != 0 ? 1 : 0);


byte[] temp = new byte[groups * base];


Arrays.fill(temp, (byte) 0);


System.arraycopy(keyByte, 0, temp, 0, keyByte.length);


keyByte = temp;


}


// 初始化


Security.addProvider(new BouncyCastleProvider());


Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");


SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");


AlgorithmParameters parameters = AlgorithmParameters


.getInstance("AES");


parameters.init(new IvParameterSpec(ivByte));


// 初始化


cipher.init(Cipher.DECRYPT_MODE, spec, parameters);


byte[] resultByte = cipher.doFinal(dataByte);


i


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


f (null != resultByte && resultByte.length > 0) {


result = new String(resultByte, "UTF-8");


}


} catch (NoSuchAlgorithmException e) {


e.printStackTrace();


} catch (NoSuchPaddingException e) {


e.printStackTrace();


} catch (InvalidParameterSpecException e) {


e.printStackTrace();


} catch (IllegalBlockSizeException e) {


e.printStackTrace();


} catch (BadPaddingException e) {


e.printStackTrace();


} catch (UnsupportedEncodingException e) {


e.printStackTrace();


} catch (InvalidKeyException e) {


e.printStackTrace();


} catch (InvalidAlgorithmParameterException e) {


e.printStackTrace();


} catch (NoSuchProviderException e) {


e.printStackTrace();


}


return result;


}


/**


  • 获取微信小程序 session_key 和 openid

  • @param code 调用微信登陆返回的 Code

  • @return


*/


public JSONObject getSessionKeyAndOpenid(String code) {


//微信端登录 code 值


String wxCode = code;


//请求地址 https://api.weixin.qq.com/sns/jscode2session


String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";


Map<String, String> requestUrlParam = new HashMap<>();


//开发者设置中的 appId


requestUrlParam.put("appid", appId);


//开发者设置中的 appSecret


requestUrlParam.put("secret", appSecret);


//小程序调用 wx.login 返回的 code


requestUrlParam.put("js_code", wxCode);


//默认参数 authorization_code


requestUrlParam.put("grant_type", "authorization_code");


//发送 post 请求读取调用微信 https://api.weixin.qq.com/sns/jscode2session 接口获取 openid 用户唯一标识


JSONObject jsonObject = JSON.parseObject(sendPost(requestUrl, requestUrlParam));


return jsonObject;


}


/**


  • 微信 数据解密<br/>

  • 对称解密使用的算法为 AES-128-CBC,数据采用 PKCS#7 填充<br/>

  • 对称解密的目标密文:encrypted=Base64_Decode(encryptData)<br/>

  • 对称解密秘钥:key = Base64_Decode(session_key),aeskey 是 16 字节<br/>

  • 对称解密算法初始向量:iv = Base64_Decode(iv),同样是 16 字节<br/>

  • @param encrypted 目标密文

  • @param session_key 会话 ID

  • @param iv 加密算法的初始向量


*/


public static String wxDecrypt(String encrypted, String session_key, String iv) {


String json = null;


byte[] encrypted64 = org.apache.tomcat.util.codec.binary.Base64.decodeBase64(encrypted);


byte[] key64 = org.apache.tomcat.util.codec.binary.Base64.decodeBase64(session_key);


byte[] iv64 = org.apache.tomcat.util.codec.binary.Base64.decodeBase64(iv);


byte[] data;


try {


init();


json = new String(decrypt(encrypted64, key64, generateIV(iv64)));


} catch (Exception e) {


e.printStackTrace();


}


return json;


}


/**


  • 初始化密钥


*/


public static void init() throws Exception {


Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());


KeyGenerator.getInstance(KEY_NAME).init(128);


}


/**


  • 生成 iv


*/


public static AlgorithmParameters generateIV(byte[] iv) throws Exception {


// iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为 0


// Arrays.fill(iv, (byte) 0x00);


AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_NAME);


params.init(new IvParameterSpec(iv));


return params;


}


/**


  • 生成解密


*/


public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv)


throws Exception {


Key key = new SecretKeySpec(keyBytes, KEY_NAME);


Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);


// 设置为解密模式


cipher.init(Cipher.DECRYPT_MODE, key, iv);


return cipher.doFinal(encryptedData);


}


/**


  • 向指定 URL 发送 POST 方法的请求

  • @param url 发送请求的 URL

  • @return 所代表远程资源的响应结果


*/


public String sendPost(String url, Map<String, ?> paramMap) {


PrintWriter out = null;


BufferedReader in = null;


String result = "";


String param = "";


Iterator<String> it = paramMap.keySet().iterator();


while (it.hasNext()) {


String key = it.next();


param += key + "=" + paramMap.get(key) + "&";


}


try {


URL realUrl = new URL(url);


// 打开和 URL 之间的连接


URLConnection conn = realUrl.openConnection();


// 设置通用的请求属性


conn.setRequestProperty("accept", "/");


conn.setRequestProperty("connection", "Keep-Alive");


conn.setRequestProperty("Accept-Charset", "utf-8");


conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");


// 发送 POST 请求必须设置如下两行


conn.setDoOutput(true);


conn.setDoInput(true);


// 获取 URLConnection 对象对应的输出流


out = new PrintWriter(conn.getOutputStream());


// 发送请求参数


out.print(param);


// flush 输出流的缓冲


out.flush();


// 定义 BufferedReader 输入流来读取 URL 的响应


in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));


String line;


while ((line = in.readLine()) != null) {


result += line;


}


} catch (Exception e) {


log.error(e.getMessage(), e);


}


//使用 finally 块来关闭输出流、输入流


finally {


try {


if (out != null) {


out.close();


}


if (in != null) {


in.close();


}


} catch (IOException ex) {


ex.printStackTrace();


}


}


return result;


}


}


工具栏里面涉及到封装写好的两个核心方法:

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
JAVA 微信小程序 解密 用户信息encryptedData