Java wechat applet decrypts user information encrypteddata

Small target youth 2021-06-23 23:19:03
java wechat applet decrypts user


  Why send this article , If you found this article by searching , I understand your bitterness .

ps:

This analysis uses PKCS7Padding, Know everything. .

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

Not much said , Code up ( Do it yourself ):

 

Import the core jar rely on :

 <dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>

WeChatUtil:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.tomcat.util.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@Component
public class WeChatUtil {
private static final Logger log = LoggerFactory.getLogger(WeChatUtil.class);
@Value("${wechat.applets.appid}")
private String appId;
@Value("${wechat.applets.appsecret}")
private String appSecret;
// Algorithm name
public static final String KEY_NAME = "AES";
// Encryption and decryption algorithm / Pattern / fill style
// ECB The mode only uses the key to encrypt and decrypt the data ,CBC The pattern needs to add a iv
public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
/**
* Wechat applet - Personal information decryption
* @param encryptedData
* @param sessionKey
* @param iv
* @return
*/
public static String getUserInfo(String encryptedData, String sessionKey, String iv) {
String result = "";
// Encrypted data
byte[] dataByte = Base64.decodeBase64(encryptedData);
// Encryption key
byte[] keyByte = Base64.decodeBase64(sessionKey);
// Offset
byte[] ivByte = Base64.decodeBase64(iv);
try {
// If you don't have enough keys 16 position , Then make up . This if The content in is very important
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;
}
// initialization
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));
// initialization
cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
byte[] resultByte = cipher.doFinal(dataByte);
if (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;
}
/**
* Get wechat applet session_key and openid
*
* @param code Call wechat login to return Code
* @return
*/
public JSONObject getSessionKeyAndOpenid(String code) {
// Wechat login code value
String wxCode = code;
// Request address https://api.weixin.qq.com/sns/jscode2session
String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
Map<String, String> requestUrlParam = new HashMap<>();
// In developer settings appId
requestUrlParam.put("appid", appId);
// In developer settings appSecret
requestUrlParam.put("secret", appSecret);
// Applet call wx.login Back to code
requestUrlParam.put("js_code", wxCode);
// Default parameters authorization_code
requestUrlParam.put("grant_type", "authorization_code");
// send out post Request to read and call wechat https://api.weixin.qq.com/sns/jscode2session Interface acquisition openid User unique identification
JSONObject jsonObject = JSON.parseObject(sendPost(requestUrl, requestUrlParam));
return jsonObject;
}
/**
* WeChat Data decryption <br/>
* The algorithm used for symmetric decryption is AES-128-CBC, Data use PKCS#7 fill <br/>
* Symmetric decryption target ciphertext :encrypted=Base64_Decode(encryptData)<br/>
* Symmetric decryption key :key = Base64_Decode(session_key),aeskey yes 16 byte <br/>
* Initial vector of symmetric decryption algorithm :iv = Base64_Decode(iv), The same is 16 byte <br/>
*
* @param encrypted Target ciphertext
* @param session_key conversation ID
* @param iv Initial vector of encryption algorithm
*/
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;
}
/**
* Initialize key
*/
public static void init() throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyGenerator.getInstance(KEY_NAME).init(128);
}
/**
* Generate iv
*/
public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
// iv For one 16 An array of bytes , Here we use and iOS End the same way of construction , All data are 0
// Arrays.fill(iv, (byte) 0x00);
AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_NAME);
params.init(new IvParameterSpec(iv));
return params;
}
/**
* Generate decryption
*/
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);
// Set to decryption mode
cipher.init(Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(encryptedData);
}
/**
* Assign to URL send out POST Method request
*
* @param url Send requested URL
* @return Response result of the remote resource represented
*/
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);
// Open and URL Connection between
URLConnection conn = realUrl.openConnection();
// Set common request properties
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)");
// send out POST The request must be set to the following two lines
conn.setDoOutput(true);
conn.setDoInput(true);
// obtain URLConnection Object corresponding output stream
out = new PrintWriter(conn.getOutputStream());
// Send request parameters
out.print(param);
// flush Buffering of output streams
out.flush();
// Definition BufferedReader Input stream to read URL Response
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);
}
// Use finally Block to close the output stream 、 Input stream
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
}

The toolbar involves two core methods of encapsulation :

 

first

According to the front-end applet passed in code obtain session_key and openid:

There's nothing wrong with that , Just don't say much .

 

the second

The front end took what we gave him  session_key and openid , He brought back the encrypted data , We need the help of the server , This is really annoying ! But seeing you here , Don't bother , Just use this one I wrote .

 

 

That's it , Take away the tool class and parse it .

 

版权声明
本文为[Small target youth]所创,转载请带上原文链接,感谢
https://javamana.com/2021/06/20210623231802910l.html

  1. Matrix architecture practice of Boshi fund's Internet open platform based on rocketmq
  2. 字节面试,我这样回答Spring中的循环依赖,拿下20k offer!
  3. Byte interview, I answer the circular dependence in spring like this, and get 20K offer!
  4. oracle 11g查看alert日志方法
  5. How to view alert log in Oracle 11g
  6. 手写Spring Config,最终一战,来瞅瞅撒!
  7. Handwritten spring config, the final battle, come and see!
  8. 用纯 JavaScript 撸一个 MVC 框架
  9. Build an MVC framework with pure JavaScript
  10. 使用springBoot实现服务端XML文件的前端界面读写
  11. Using springboot to read and write the front interface of server XML file
  12. 【Javascript + Vue】实现随机生成迷宫图片
  13. [Javascript + Vue] random generation of maze pictures
  14. 大数据入门:Hadoop伪分布式集群环境搭建教程
  15. Introduction to big data: Hadoop pseudo distributed cluster environment building tutorial
  16. 八股文骚套路之Java基础
  17. commons-collections反序列化利用链分析(3)
  18. Java foundation of eight part wensao routine
  19. Analysis of common collections deserialization utilization chain (3)
  20. dubbogo 社区负责人于雨说
  21. Yu Yu, head of dubbogo community, said
  22. dubbogo 社区负责人于雨说
  23. Yu Yu, head of dubbogo community, said
  24. 设计模式 选自《闻缺陷则喜》此书可免费下载
  25. The design pattern is selected from the book "you are happy when you hear defects", which can be downloaded free of charge
  26. xDAI被选为 Swarm 的侧链解决方案,将百倍降低 Swarm 网络Gas费
  27. L2 - 深入理解Arbitrum
  28. Xdai is selected as the side chain solution of swarm, which will reduce the gas cost of swarm network 100 times
  29. L2 - deep understanding of arbitrum
  30. Java全栈方向学习路线
  31. 设计模式学习04(Java实现)——单例模式
  32. Java full stack learning route
  33. Design pattern learning 04 (Java implementation) - singleton pattern
  34. Mybatis学习01:利用mybatis查询数据库
  35. Mybatis learning 01: using mybatis to query database
  36. Java程序员从零开始学Vue(01)- 前端发展史
  37. Java程序员从零开始学Vue(05)- 基础知识快速补充(html、css、js)
  38. Java programmers learn Vue from scratch
  39. Java programmers learn Vue from scratch (05) - quick supplement of basic knowledge (HTML, CSS, JS)
  40. 【Java并发编程实战14】构建自定义同步工具(Building-Custom-Synchronizers)
  41. [Java Concurrent Programming Practice 14] building custom Synchronizers
  42. 【源码分析】- 在SpringBoot中你会使用REST风格处理请求吗?
  43. [source code analysis] - do you use rest style to process requests in springboot?
  44. 框架篇:见识一下linux高性能网络IO+Reactor模型
  45. Framework: see Linux high performance network IO + reactor model
  46. 基础篇:JAVA.Stream函数,优雅的数据流操作
  47. 基础篇:异步编程不会?我教你啊!CompletableFuture(JDK1.8)
  48. Basic part: Java. Stream function, elegant data stream operation
  49. Basic: asynchronous programming won't? I'll teach you! CompletableFuture(JDK1.8)
  50. 技能篇:sed教程-linux命令
  51. 数据库篇:mysql内置函数
  52. Linux 主要的发行系统版本介绍
  53. 网络篇:朋友面试之https认证加密过程
  54. Skills: sed tutorial - Linux command
  55. Database: built in functions of MySQL
  56. Introduction of Linux main distribution system versions
  57. Network: friends interview: the encryption process of HTTPS authentication
  58. [Linux]经典面试题 - 系统管理 - 备份策略
  59. 解决java socket在传输汉字时出现截断导致乱码的问题
  60. [Linux] classic interview questions system management backup strategy