package com.ruoyi.payment.wx.utils;
|
|
import com.ruoyi.payment.wx.pojo.AppletUserDecodeData;
|
import lombok.extern.slf4j.Slf4j;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import org.bouncycastle.util.encoders.Base64;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import javax.crypto.Cipher;
|
import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.SecretKeySpec;
|
import javax.servlet.ServletInputStream;
|
import javax.servlet.http.HttpServletRequest;
|
import java.io.BufferedReader;
|
import java.io.IOException;
|
import java.io.InputStreamReader;
|
import java.security.AlgorithmParameters;
|
import java.security.SecureRandom;
|
import java.security.Security;
|
import java.util.Arrays;
|
import java.util.Random;
|
|
/**
|
* @Description 获取用户信息工具类
|
* @Author xiaochen
|
* @Date 2021/8/12 15:45
|
*/
|
@Slf4j
|
public class WxUtils {
|
/**
|
* 随机字符
|
*/
|
private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
private static final Random RANDOM = new SecureRandom();
|
|
/**
|
* 微信小程序API 用户数据的解密
|
* @param encryptedData
|
* @param sessionKey
|
* @param iv
|
* @return
|
*/
|
public static AppletUserDecodeData encryptedData(String encryptedData, String sessionKey, String iv) {
|
// 被加密的数据
|
byte[] dataByte = Base64.decode(encryptedData);
|
// 加密秘钥
|
byte[] keyByte = Base64.decode(sessionKey);
|
// 偏移量
|
byte[] ivByte = Base64.decode(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);
|
if (null != resultByte && resultByte.length > 0) {
|
String result = new String(resultByte, "UTF-8");
|
log.info("解密原串:{}",result);
|
return WxJsonUtils.parseObject(result, AppletUserDecodeData.class);
|
}
|
throw new RuntimeException("解密的数据为空");
|
} catch (Exception e) {
|
log.error("解密失败. error = {}", e.getMessage(), e);
|
throw new RuntimeException(e.getMessage());
|
}
|
}
|
|
/**
|
* 微信小程序API 用户数据的签名验证
|
* signature = sha1( rawData + session_key )
|
*
|
* @param rawData 不包括敏感信息的原始数据字符串,用于计算签名。
|
* @param sessionKey
|
*/
|
public static void verifySignature(String rawData, String sessionKey, String signature) {
|
String serverSignature = SHA1.getSHA1(rawData + sessionKey);
|
System.out.println(rawData + sessionKey);
|
log.info(rawData + ">>>>>>:" + sessionKey + " === " + serverSignature + " ======" + signature);
|
if (!signature.equals(serverSignature)) {
|
throw new RuntimeException("数据验签不通过");
|
}
|
}
|
|
/**
|
* 根据流接收请求数据
|
*
|
* @param request
|
* @return
|
*/
|
public static String streamBodyByReceive(HttpServletRequest request) throws IOException {
|
BufferedReader reader = null;
|
StringBuffer sb = new StringBuffer();
|
try {
|
ServletInputStream stream = request.getInputStream();
|
// 获取响应
|
reader = new BufferedReader(new InputStreamReader(stream));
|
String line;
|
while ((line = reader.readLine()) != null) {
|
sb.append(line);
|
}
|
} catch (IOException e) {
|
throw new RuntimeException("读取微信支付接口数据流出现异常!");
|
} finally {
|
reader.close();
|
WxUtils.info(sb.toString());
|
}
|
return sb.toString();
|
}
|
|
/**
|
* 获取随机字符串 Nonce Str
|
*
|
* @return String 随机字符串
|
*/
|
public static String generateNonceStr() {
|
char[] nonceChars = new char[32];
|
for (int index = 0; index < nonceChars.length; ++index) {
|
nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
|
}
|
return new String(nonceChars);
|
}
|
|
/**
|
* 获取当前时间戳,单位秒
|
*
|
* @return
|
*/
|
public static long getCurrentTimestamp() {
|
return System.currentTimeMillis() / 1000;
|
}
|
|
/**
|
* 获取当前时间戳,单位毫秒
|
*
|
* @return
|
*/
|
public static long getCurrentTimestampMs() {
|
return System.currentTimeMillis();
|
}
|
|
|
/**
|
* 日志
|
*
|
* @return
|
*/
|
public static Logger getLogger() {
|
Logger logger = LoggerFactory.getLogger("wxpay java sdk --->");
|
return logger;
|
}
|
|
/**
|
* debug
|
*
|
* @param msg
|
* @param args
|
*/
|
public static void debug(String msg, Object... args) {
|
Logger log = getLogger();
|
if (log.isDebugEnabled()) {
|
log.debug(msg, args);
|
}
|
}
|
|
/**
|
* info
|
*
|
* @param msg
|
* @param args
|
*/
|
public static void info(String msg, Object... args) {
|
Logger log = getLogger();
|
if (log.isInfoEnabled()) {
|
log.info(msg, args);
|
}
|
}
|
|
/**
|
* warn
|
*
|
* @param msg
|
* @param args
|
*/
|
public static void warn(String msg, Object... args) {
|
Logger log = getLogger();
|
if (log.isWarnEnabled()) {
|
log.warn(msg, args);
|
}
|
}
|
|
/**
|
* error
|
*
|
* @param msg
|
* @param args
|
*/
|
public static void error(String msg, Object... args) {
|
Logger log = getLogger();
|
if (log.isErrorEnabled()) {
|
log.error(msg, args);
|
}
|
}
|
}
|