package com.zbkj.common.utils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
public class PaySigCalculator {
public static void main(String[] args) throws Exception {
// 固定 URI,不带 query 参数
String uri = "/retail/B2b/getorder";
// 固定 post_body,确保与 HTTP 请求中的 body 完全一致
String postBody = "{\"amount\":{\"order_amount\":14500},\"mchid\":\"1199752250\",\"out_trade_no\":\"SLFWX221173319180772358787\",\"description\":\"\\u7ea2\\u85af\\u6df1\\u52a0\\u5de5\\u4ea7\\u54c1\",\"env\":0}";
// 固定 appKey,实际使用需根据环境替换
String appKey = "SLG6lTnQNewdddddK1zxddy1lgzAO0";
// step1: 计算 pay_sig(支付签名)
String paySig = calcPaySig(uri, postBody, appKey);
System.out.println("pay_sig: " + paySig);
// 验证 pay_sig,确保计算结果与预期一致
// assert paySig.equals("2cb3e9fda4da9774f0c6f747bbf6c56e9045969d9921db7344fffdc945c1dc23");
// 固定 session_key,需根据实际用户登录态替换
String sessionKey = "k+tO0266AFk3LXgKC9Xh/A==";
// step2: 计算 signature(用户登录态签名)
String signature = calcSignature(postBody, sessionKey);
System.out.println("signature: " + signature);
// 验证 signature,确保计算结果与预期一致
// assert signature.equals("47784191c740b0522d39d0a3926a19aa0e30c77975f689a9739c9553ffac2d9d");
}
public static String getPaySig(String postBody) {
String calcPaySig = "";
// URI,不带参数部分
String uri = "/retail/B2b/getorder";
// appKey为假设值,请根据实际环境替换
//SLG6lTnQNewdffffLy1lgzAO0
String appKey = "SLG6lTnQNewlr6PfffDddgzAO0";
try {
calcPaySig = calcPaySig(uri, appKey, postBody);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return calcPaySig;
}
public static String getSignature(String body,String sessionKey) {
String signature = null;
try {
signature = calcSignature(body, sessionKey);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("signature: " + signature);
return signature;
}
/**
* 计算 pay_sig 签名
*
* @param uri 当前请求的 API 的 URI 部分,不带 query 参数
* @param postBody HTTP POST 的数据包体
* @param appKey 对应环境的 AppKey
* @return 支付请求签名 pay_sig
* @throws Exception
*/
public static String calcPaySig(String uri, String postBody, String appKey) throws Exception {
// 拼接签名字符串:uri + "&" + post_body
String needSignMsg = uri + "&" + postBody;
return hmacSha256(appKey, needSignMsg);
}
/**
* 计算 signature 签名
*
* @param postBody HTTP POST 的数据包体
* @param sessionKey 当前用户有效的 session_key
* @return 用户登录态签名 signature
* @throws Exception
*/
public static String calcSignature(String postBody, String sessionKey) throws Exception {
// 签名字符串直接为 post_body
return hmacSha256(sessionKey, postBody);
}
/**
* HMAC-SHA256 签名算法
*
* @param key 加密密钥
* @param msg 签名内容
* @return 签名结果的十六进制字符串
* @throws Exception
*/
public static String hmacSha256(String key, String msg) throws Exception {
try {
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
hmacSha256.init(secretKey);
byte[] hash = hmacSha256.doFinal(msg.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hash);
} catch (Exception e) {
throw new SignatureException("Error while generating HMAC-SHA256 signature: " + e.getMessage());
}
}
/**
* 将字节数组转换为十六进制字符串
*
* @param bytes 输入字节数组
* @return 十六进制字符串
*/
public static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
}
这是Java版的代码,运行main方法签名没错误, 但是通过项目动态传值,前段小程序执行后就是报错签名错误。请问如何解决呢。
问题解决了么?