jiangqs
2023-07-01 2dcfe238ab12f4f18cbd5705a6af5357b367a886
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package com.ruoyi.shop.util;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
/**
 * @date 2020-03-18 11:02
 * @description 签名相关
 */
public class SignUtils {
    private static final Logger logger = LoggerFactory.getLogger(SignUtils.class);
 
    /**
     * 签名生成
     * @param method 请求方法 如POST
     * @param urlSuffix 请求地址后缀 如/v3/certificates
     * @param mchId 电商平台商户号
     * @param serialNo 电商平台商户API证书序列号
     * @param body 请求请求报文主体,如果没有,就传空字符串
     * @param mchPrivateKeyPath 电商平台商户API私钥
     * @return
     */
    /*public static String authorization(String method,String urlSuffix,String mchId,String serialNo,String body,String mchPrivateKeyPath) {
        try {
            String mchPrivateKey = CertificateUtils.getPrivateKey(mchPrivateKeyPath);
            //时间戳
            String timestamp = Long.toString(System.currentTimeMillis()/1000);
            //随机数
            String nonceStr = IdUtils.randomUUID();
 
            //拼签名串
            StringBuilder sb = signMessage(method,urlSuffix,timestamp,nonceStr,body);
 
            logger.info("sign original string:{}",sb.toString());
 
            //计算签名
            String sign = new String(Base64.encodeBase64(v3signRSA(sb.toString(),mchPrivateKey)));
 
            logger.info("sign result:{}",sign);
 
            //拼装http头的Authorization内容
            String authorization ="WECHATPAY2-SHA256-RSA2048 mchid=\""+mchId+"\",nonce_str=\""+nonceStr+"\",signature=\""+sign+"\",timestamp=\""+timestamp+"\",serial_no=\""+serialNo+"\"";
 
            logger.info("authorization result:{}",authorization);
 
            return authorization;
 
        } catch (Exception e) {
            logger.error("authorization Exception result:{}",e);
            e.printStackTrace();
            return null;
        }
    }
 
    *//**
     * Authorization 签名串
     * @param method
     * @param urlSuffix
     * @param timestamp
     * @param nonceStr
     * @param body
     * @return
     *//*
    private static StringBuilder signMessage(String method,String urlSuffix,String timestamp,String nonceStr,String body) {
        return new StringBuilder()
                .append(method)
                .append("\n")
                .append(urlSuffix)
                .append("\n")
                .append(timestamp)
                .append("\n")
                .append(nonceStr)
                .append("\n")
                .append(body)
                .append("\n");
    }
 
    *//**
     * 私钥签名
     * @param data 需要加密的数据
     * @param mchPriKey
     * @return
     * @throws Exception
     *//*
    public static byte[] v3signRSA(String data, String mchPriKey) throws Exception {
        //签名的类型
        Signature sign = Signature.getInstance("SHA256withRSA");
        //读取商户私钥,该方法传入商户私钥证书的内容即可
        byte[] keyBytes = Base64.decodeBase64(mchPriKey);
        PKCS8EncodedKeySpec keySpec =new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey priKey = keyFactory.generatePrivate(keySpec);
        sign.initSign(priKey);
        sign.update(data.getBytes(StandardCharsets.UTF_8));
        return sign.sign();
    }
 
    public static boolean v3VerifyRSA(HttpResponse response,String wechatPubKeyPath) {
 
        if (response == null || StringUtils.isEmpty(wechatPubKeyPath)) {
            return false;
        }
        Map<String, List<String>> headers = response.headers();
        //验证微信支付返回签名
        String headsTimestamp = headers.get("Wechatpay-Timestamp").get(0);
        String headsNonce = headers.get("Wechatpay-Nonce").get(0);
        String headsSign = headers.get("Wechatpay-Signature").get(0);
        String resContent = response.body();
        //拼装待签名串
        StringBuilder sb =new StringBuilder();
        sb.append(headsTimestamp).append("\n");
        sb.append(headsNonce).append("\n");
        sb.append(resContent).append("\n");
        try {
            //验证签名
            return v3VerifyRSA(sb.toString(), Base64.decodeBase64(headsSign.getBytes()), wechatPubKeyPath);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    public static boolean v3VerifyRSA(String data,byte[] sign, String wechatPubKeyPath) throws Exception{
        if(data == null || sign == null || wechatPubKeyPath == null){
            return false;
        }
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        FileInputStream in =new FileInputStream(wechatPubKeyPath);
        Certificate c = cf.generateCertificate(in);
        in.close();
        PublicKey publicKey = c.getPublicKey();
        Signature signature = Signature.getInstance("SHA256WithRSA");
        signature.initVerify(publicKey);
        signature.update(data.getBytes(StandardCharsets.UTF_8));
 
        boolean result = signature.verify(sign);
        if (result) {
            logger.info("v3VerifyRSA result:{}","签名验证成功");
        } else {
            logger.info("v3VerifyRSA result:{}","签名验证失败");
        }
        return result;
    }*/
}