Java 签名验签工具类
public class SignatureUtil { private static final String CHARSET = "UTF-8"; private static final String SIGN_TYPE = "MD5"; /** * 判断签名是否正确,必须包含sign字段,否则返回false。 * * @param data Map类型数据 * @param key API密钥 * @return 签名是否正确 * @throws Exception */ public static boolean check(Map<String, String> data, String key, String signField){ if (!data.containsKey(signField)) { return false; } String sign = data.get(signField); return sign(data, key, signField).equals(sign); } /** * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。 * * @param data 待签名数据 * @param key API密钥 * @return 签名 */ public static String sign(final Map<String, String> data, String key, String signField) { Set<String> keySet = data.keySet(); String[] keyArray = keySet.toArray(new String[keySet.size()]); Arrays.sort(keyArray); StringBuilder sb = new StringBuilder(); for (String k : keyArray) { if (k.equals(signField)) { continue; } // 参数值为空,则不参与签名 if (data.get(k).trim().length() > 0) { sb.append(k).append("=").append(data.get(k).trim()).append("&"); } } sb.append("key=").append(key); System.out.println("验签封装的串为:"+sb); String result=MD5(sb.toString()).toUpperCase(); System.out.println("生成的签名为:"+result); return result; } /** * 生成 MD5 * * @param data 待处理数据 * @return MD5结果 */ private static String MD5(String data) { try { MessageDigest md = MessageDigest.getInstance(SIGN_TYPE); byte[] array = md.digest(data.getBytes(CHARSET)); StringBuilder sb = new StringBuilder(); for (byte item : array) { sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); } return sb.toString().toUpperCase(); } catch (Exception e){ throw new RuntimeException(e); } } }
上面的签名工具类,下面是示例。
验签示例:
Map<String, String> params = new TreeMap<>(); params.put("channel", commonRequest.getChannel()); params.put("data", commonRequest.getData()); params.put("sign", commonRequest.getSign()); //检查签名 SignatureUtil.check(params, signKey, "sign");
生成签名示例:
Map<String, String> map = new HashMap<>(); map.put("channel", "app"); map.put("data", DESUtil.Des3EncodeCBC(desKey, JSON.toJSONString(request)).replaceAll("\r\n|\r|\n|\n\r", "")); String sign = SignatureUtil.sign(map, signKey, "sign"); map.put("sign", sign);
注意:进行DES加密时,加密后的字符串里包含\n等特殊字符,需要替换掉。