package com.dsh.course.util.wx;
|
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
import java.io.BufferedReader;
|
import java.io.FileReader;
|
import java.nio.charset.StandardCharsets;
|
import java.security.KeyFactory;
|
import java.security.PrivateKey;
|
import java.security.Security;
|
import java.security.Signature;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.util.ArrayList;
|
import java.util.Base64;
|
import java.util.List;
|
import java.util.Map;
|
|
public class WeChatV3SignUtil {
|
|
static {
|
Security.addProvider(new BouncyCastleProvider());
|
}
|
|
/**
|
* 从 PEM 文件中读取私钥内容
|
*/
|
public static PrivateKey loadPrivateKeyFromPem(String pemFilePath) throws Exception {
|
StringBuilder sb = new StringBuilder();
|
try (BufferedReader reader = new BufferedReader(new FileReader(pemFilePath))) {
|
String line;
|
while ((line = reader.readLine()) != null) {
|
if (!line.startsWith("-----") && !line.endsWith("-----")) {
|
sb.append(line);
|
}
|
}
|
}
|
|
byte[] pkcs8Bytes = Base64.getDecoder().decode(sb.toString());
|
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8Bytes);
|
KeyFactory kf = KeyFactory.getInstance("RSA", "BC");
|
return kf.generatePrivate(keySpec);
|
}
|
|
/**
|
* 构造待签名字符串(按 key 字典序排序)
|
*/
|
public static String buildSignMessage(Map<String, Object> map) {
|
List<String> keys = new ArrayList<>(map.keySet());
|
// Collections.sort(keys);
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append(map.get("appid")).append("\n");
|
sb.append(map.get("timestamp")).append("\n");
|
sb.append(map.get("noncestr")).append("\n");
|
sb.append(map.get("prepayid")).append("\n");
|
return sb.toString();
|
}
|
|
/**
|
* 使用商户私钥生成签名(SHA256withRSA + Base64)
|
*/
|
public static String signWithPrivateKey(String message, String privateKeyPath) throws Exception {
|
PrivateKey privateKey = loadPrivateKeyFromPem(privateKeyPath);
|
|
Signature signature = Signature.getInstance("SHA256withRSA");
|
signature.initSign(privateKey);
|
signature.update(message.getBytes(StandardCharsets.UTF_8));
|
byte[] signedBytes = signature.sign();
|
|
return Base64.getEncoder().encodeToString(signedBytes);
|
}
|
}
|