mitao
2024-06-06 3d2b51ea4520533de5e78f88dddf5b5c7dce4247
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.sinata.rest.common;
 
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.alipay.api.internal.util.StreamUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
 
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
 
public class SignatureUtil {
 
    public static final String SIGN_TYPE_RSA = "RSA";
 
    public static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";
 
    /**
     * 私钥加签
     *
     * @param content    内容
     * @param privateKey 私钥
     * @param charset    编码
     * @return sgin
     * @throws Exception 异常
     */
    public static String rsa256Sign(String content, String privateKey,
                                    String charset) throws Exception {
        try {
            PrivateKey priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA,
                    new ByteArrayInputStream(privateKey.getBytes()));
            java.security.Signature signature = java.security.Signature
                    .getInstance(SIGN_SHA256RSA_ALGORITHMS);
            signature.initSign(priKey);
            if (StrUtil.isEmpty(charset)) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }
            byte[] signed = signature.sign();
            return new String(Base64.encodeBase64(signed));
        } catch (Exception e) {
            throw new Exception("无效签名;RSAcontent = " + content + "; charset = " + charset, e);
        }
 
    }
 
 
    public static PrivateKey getPrivateKeyFromPKCS8(String algorithm,
                                                    InputStream ins) throws Exception {
        if (ins == null || StrUtil.isEmpty(algorithm)) {
            return null;
        }
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        byte[] encodedKey = StreamUtil.readText(ins, "UTF-8").getBytes();
        encodedKey = Base64.decodeBase64(encodedKey);
        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
    }
 
    /**
     * 公钥验签
     *
     * @param content   内容
     * @param sign      私钥签名
     * @param publicKey 公钥
     * @param charset   编码
     * @return
     * @throws Exception
     */
    public static boolean rsa256CheckContent(String content, String sign, String publicKey,
                                             String charset) throws Exception {
        try {
            PublicKey pubKey = getPublicKeyFromX509("RSA",
                    new ByteArrayInputStream(publicKey.getBytes()));
            java.security.Signature signature = java.security.Signature
                    .getInstance(SIGN_SHA256RSA_ALGORITHMS);
            signature.initVerify(pubKey);
            if (StrUtil.isEmpty(charset)) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }
            return signature.verify(Base64.decodeBase64(sign.getBytes()));
        } catch (Exception e) {
            throw new Exception("无效签名;RSAcontent = " + content + "; charset = " + charset, e);
        }
    }
 
    public static PublicKey getPublicKeyFromX509(String algorithm,
                                                 InputStream ins) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        StringWriter writer = new StringWriter();
        StreamUtil.io(new InputStreamReader(ins), writer);
        byte[] encodedKey = writer.toString().getBytes();
        encodedKey = Base64.decodeBase64(encodedKey);
        return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
    }
 
    public static String getAsciiJsonString(JSONObject json) {
        //将key值单独封装成List
        List<String> keys = new ArrayList<String>(((Map<String, Object>) json).keySet());
        //排序
        Collections.sort(keys);
        //使用LinkedHashMap记录插入顺序
        LinkedHashMap<String, Object> linkmap = new LinkedHashMap<String, Object>();
        //按照key值顺序插入对应的value
        for (String key : keys) {
            if (StringUtils.isNotEmpty(key)) {
                linkmap.put(key, ((Map<String, Object>) json).get(key));
            }
        }
        //将LinkedHashMap转换为JSONObject
        JSONObject jObject = new JSONObject(true);
        jObject.putAll(linkmap);
        //返回JSON字符串
        return jObject.toString();
    }
 
 
    public static String getSignContent(Map<String, String> sortedParams) {
        StringBuffer content = new StringBuffer();
        List<String> keys = new ArrayList<>(sortedParams.keySet());
        Collections.sort(keys);
        int index = 0;
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = sortedParams.get(key);
            if (StrUtil.isAllNotEmpty(key, value)) {
                content.append((index == 0 ? "" : "&") + key + "=" + value);
                index++;
            }
        }
        return content.toString();
    }
}