xuekang
2024-05-11 bac0878349a1db23e7b420ea164e22fb9db73a99
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
package com.nuvole.hnnx.hnnxPay;
 
import com.csii.sg.codec.Hex;
import org.springframework.util.Assert;
 
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.*;
 
/**
 * @author awlwen
 * @since 2017/11/30
 */
public class SignatureSigner {
    /**
     * 将字节数组转换为16进制字符串
     * 算法:
     * 将字节数组中每个字节取出后转换为16进制,截取低八位
     * 将不足2位的字符前补0,解析时可按2位分隔
     *
     * @param byteArray 字节数组
     * @return 16进制字符
     */
    private String byteToHex(byte[] byteArray) {
        if (byteArray == null) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < byteArray.length; i++) {
            String hexString = Integer.toHexString(byteArray[i] & 0x00ff);
            if (hexString.length() != 2) {
                //如果字符长度不为2位,前补0占位
                sb.append("0");
            }
            sb.append(hexString);
        }
        return sb.toString();
    }
 
private static byte[] signLow(String plain, String algorithm, PrivateKey privateKey) {
        Assert.notNull(plain, "plain is null.");
        Assert.notNull(algorithm, "algorithm is null.");
        Assert.notNull(privateKey, "private key is null.");
        try {
            Signature sign = Signature.getInstance(algorithm);
            sign.initSign(privateKey);
            sign.update(plain.getBytes());
            return sign.sign();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
 
private static byte[] signLowByte(byte[] plain, String algorithm, PrivateKey privateKey) {
        Assert.notNull(plain, "plain is null.");
        Assert.notNull(algorithm, "algorithm is null.");
        Assert.notNull(privateKey, "private key is null.");
        try {
            Signature sign = Signature.getInstance(algorithm);
            sign.initSign(privateKey);
            sign.update(plain);
            return sign.sign();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
 
    public static String laBaSign(Map<String, String> parameters, String accessKeySecret) {
        // Step 1: Sort the parameters by key in ascending order
        List<Map.Entry<String, String>> sortedParams = new ArrayList<>(parameters.entrySet());
        Collections.sort(sortedParams, Comparator.comparing(Map.Entry::getKey));
 
        // Step 2: Generate the string to sign
        StringBuilder stringToSign = new StringBuilder();
        for (Map.Entry<String, String> param : sortedParams) {
            if (param.getValue() != null && !param.getValue().isEmpty()) {
                stringToSign.append(param.getKey()).append("=").append(param.getValue()).append("&");
            }
        }
        stringToSign.deleteCharAt(stringToSign.length() - 1); // Remove the last '&'
 
        // Step 3: Generate the signature
        try {
            Mac hmacSha256 = Mac.getInstance("HmacSHA256");
            SecretKeySpec keySpec = new SecretKeySpec(accessKeySecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            hmacSha256.init(keySpec);
            byte[] signData = hmacSha256.doFinal(stringToSign.toString().getBytes(StandardCharsets.UTF_8));
 
            // Step 4: Base64 encode the signature
            return Base64.getEncoder().encodeToString(signData);
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        return null;
    }
    /**
     * 使用提供的算法与私钥对交易数据签名
     *
     * @param plain      交易数据明文
     * @param privateKey java.security.PrivateKey 私钥
     * @return 签名
     */
    public String sign(String plain, PrivateKey privateKey) {
        byte[] bytes = signLow(plain, HnnxConstant.ALGORITHM, privateKey);
        return Hex.toHex(bytes);
    }
 
    /**
     * 快捷支付sign
     *
     * @param plain
     * @param privateKey
     * @return
     */
    public String kjSign(String plain, PrivateKey privateKey) {
        byte[] bytes = new byte[0];
        try {
            bytes = signLowByte(plain.getBytes("utf-8"), HnnxConstant.KJ_ALGORITHM, privateKey);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return Base64.getEncoder().encodeToString(bytes);
    }
 
}