package org.jeecg.modules.milk.utils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.Random;
@Slf4j
public class WxV3Authorization {
public static String getAuthorization(String method, HttpUrl url, String body, String mchid, String serialNo, String authorizationType, String serialPath){
String nonceStr = generateNonceStr();
long timestamp = System.currentTimeMillis() / 1000;
String message = buildMessage(method, url, timestamp, nonceStr, body);
String signature = null;
try {
signature = sign(message.getBytes("utf-8"), serialPath);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return authorizationType + "mchid=\"" + mchid + "\","
+ "nonce_str=\"" + nonceStr + "\","
+ "signature=\"" + signature + "\","
+ "timestamp=\"" + timestamp + "\","
+ "serial_no=\"" + serialNo + "\"";
}
private static String sign(byte[] message, String serialPath){
try {
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initSign(getPrivateKey(serialPath));
sign.update(message);
return Base64.getEncoder().encodeToString(sign.sign());
} catch (SignatureException | InvalidKeyException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
String canonicalUrl = url.encodedPath();
if (url.encodedQuery() != null) {
canonicalUrl += "?" + url.encodedQuery();
}
return method + "\n"
+ canonicalUrl + "\n"
+ timestamp + "\n"
+ nonceStr + "\n"
+ body + "\n";
}
private static PrivateKey getPrivateKey(String filename){
try {
String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");
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) {
log.debug("当前Java环境不支持RSA");
e.printStackTrace();
} catch (InvalidKeySpecException e) {
log.debug("无效的密钥格式");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static String generateNonceStr() {
String symbols = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random random = new SecureRandom();
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);
}
}