平台收付通商户进件提示“错误的签名,验签失败”?
这是我生成签名的代码,实在找不出问题出在哪里了 {"code":"SIGN_ERROR","detail":{"field":"signature","location":"authorization","sign_information":{"method":"POST","truncated_sign_message":"POST\n/v3/ecommerce/applyments/\n1709573143\nL733TZZTIS\n{}\n","sign_message_length":56,"url":"/v3/ecommerce/applyments/"},"detail":{"issue":"sign not match"}},"message":"错误的签名,验签失败"}
import cn.hutool.core.util.RandomUtil;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
public class WxAuthorizationUtil {
/**
* 得到签名信息
* @param method
* @param url
* @param body
* @return
* @throws Exception
*/
public static String getAuthorization(String method, String url, String body) throws Exception {
String nonceStr = RandomUtil.randomStringUpper(10);;
long timestamp = System.currentTimeMillis() / 1000;
String message = buildMessage(method, url, timestamp, nonceStr, body);
String signature = sign(message.getBytes("utf-8"));
String MCHID_JDKJ = "";
String MCHSERIALNO_JDKJ = "";
String httpAuthorization = "mchid=\"" + MCHID_JDKJ + "\","
+ "nonce_str=\"" + nonceStr + "\","
+ "signature=\"" + signature + "\","
+ "timestamp=\"" + timestamp + "\","
+ "serial_no=\"" + MCHSERIALNO_JDKJ + "\"";
httpAuthorization = "WECHATPAY2-SHA256-RSA2048 " + httpAuthorization;
return httpAuthorization;
}
/**
* 获取签名值
* @param message
* @return
* @throws Exception
*/
public static String sign(byte[] message) throws Exception {
Signature sign = Signature.getInstance("SHA256withRSA");
PrivateKey merchantPrivateKey = getPrivateKey("");
sign.initSign(merchantPrivateKey);
sign.update(message);
return Base64.getEncoder().encodeToString(sign.sign());
}
/**
* 获取私钥。
* @param filename 私钥文件路径 (required)
* @return 私钥对象
*/
public static PrivateKey getPrivateKey(String filename) throws IOException {
String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");
try {
String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s+", "");
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(
new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("当前Java环境不支持RSA", e);
} catch (InvalidKeySpecException e) {
throw new RuntimeException("无效的密钥格式");
}
}
/**
* 构造签名串
* 签名串一共有五行,每一行为一个参数。行尾以 \n(换行符,ASCII编码值为0x0A)结束,包括最后一行。如果参数本身以\n结束,也需要附加一个\n
* HTTP请求方法\n
* URL\n
* 请求时间戳\n
* 请求随机串\n
* 请求报文主体\n
* @param method
* @param url
* @param timestamp
* @param nonceStr
* @param body
* @return
* @throws Exception
*/
public static String buildMessage(String method, String url, long timestamp, String nonceStr, String body) {
return method + "\n"
+ url + "\n"
+ timestamp + "\n"
+ nonceStr + "\n"
+ body + "\n";
}
}