xiaoyong931011
2022-07-27 3280d1bd977e8fb5c9c60e615612fabb7b99c3e3
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
144
package cc.mrbird.febs.pay.util;
 
import org.apache.commons.codec.digest.DigestUtils;
import org.xml.sax.SAXException;
 
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
 
/**
 * User: rizenguo Date: 2014/10/29 Time: 15:23
 */
public class Signature {
    /**
     * 签名算法
     * 
     * @param o
     *            要参与签名的数据对象
     * @return 签名
     * @throws IllegalAccessException
     */
    public static String getSign(Object o,String paySecret) throws IllegalAccessException {
        ArrayList<String> list = new ArrayList<String>();
        Class<? extends Object> cls = o.getClass();
        Field[] fields = cls.getDeclaredFields();
        for (Field f : fields) {
            f.setAccessible(true);
            if (f.get(o) != null && f.get(o) != "") {
                list.add(f.getName() + "=" + f.get(o) + "&");
            }
        }
        int size = list.size();
        String[] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" +paySecret;
        Util.log("Sign Before MD5:" + result);
        result = MD5.MD5Encode(result).toUpperCase();
        Util.log("Sign Result:" + result);
        return result;
    }
 
    public static String getSign(Map<String, Object> map,String paySecret) {
        ArrayList<String> list = new ArrayList<String>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (entry.getValue() != "") {
                list.add(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        int size = list.size();
        String[] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + paySecret;
        Util.log("Sign Before MD5:" + result);
        result = MD5.MD5Encode(result).toUpperCase();
        Util.log("Sign Result:" + result);
        return result;
    }
 
    /**
     * 从API返回的XML数据里面重新计算一次签名
     * 
     * @param responseString
     *            API返回的XML数据
     * @return 新鲜出炉的签名
     * @throws ParserConfigurationException
     * @throws IOException
     * @throws SAXException
     */
    public static String getSignFromResponseString(String responseString,String paySecret)
            throws IOException, SAXException, ParserConfigurationException {
        Map<String, Object> map = XMLParser.getMapFromXML(responseString);
        // 清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
        map.put("sign", "");
        // 将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
        return Signature.getSign(map,paySecret);
    }
 
    /**
     * 检验API返回的数据里面的签名是否合法,避免数据在传输的过程中被第三方篡改
     * 
     * @param responseString
     *            API返回的XML数据字符串
     * @return API签名是否合法
     * @throws ParserConfigurationException
     * @throws IOException
     * @throws SAXException
     */
    public static boolean checkIsSignValidFromResponseString(String responseString,String paySecret)
            throws ParserConfigurationException, IOException, SAXException {
 
        Map<String, Object> map = XMLParser.getMapFromXML(responseString);
        Util.log(map.toString());
 
        String signFromAPIResponse = map.get("sign").toString();
        if (signFromAPIResponse == "" || signFromAPIResponse == null) {
            Util.log("API返回的数据签名数据不存在,有可能被第三方篡改!!!");
            return false;
        }
        Util.log("服务器回包里面的签名是:" + signFromAPIResponse);
        // 清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
        map.put("sign", "");
        // 将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
        String signForAPIResponse = Signature.getSign(map,paySecret);
 
        if (!signForAPIResponse.equals(signFromAPIResponse)) {
            // 签名验不过,表示这个API返回的数据有可能已经被篡改了
            Util.log("API返回的数据签名验证不通过,有可能被第三方篡改!!!");
            return false;
        }
        Util.log("恭喜,API返回的数据签名验证通过!!!");
        return true;
    }
    
 
 
    /**
     * 
    *  JS-SDK权限验证的签名
    * @author:姜友瑶    
    * 返回类型  void    
    * @date 2016年10月18日
     */
    public static String getJsSdkSign(String jsapi_ticket,String noncestr,String timestamp,String url) {
        String string1="jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;
        Util.log("Sign Before sha1Hex:" + string1);
        String signature= DigestUtils.sha1Hex(string1);
        Util.log("Sign Before sha1Hex:" + signature);
        return signature;
    }
 
}