Signature.java 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package com.tencent.common;
  2. import org.xml.sax.SAXException;
  3. import javax.xml.parsers.ParserConfigurationException;
  4. import java.io.IOException;
  5. import java.lang.reflect.Field;
  6. import java.util.ArrayList;
  7. import java.util.Arrays;
  8. import java.util.Map;
  9. /**
  10. * User: rizenguo
  11. * Date: 2014/10/29
  12. * Time: 15:23
  13. */
  14. public class Signature {
  15. /**
  16. * 签名算法
  17. * @param o 要参与签名的数据对象
  18. * @return 签名
  19. * @throws IllegalAccessException
  20. */
  21. public static String getSign(Object o) throws IllegalAccessException {
  22. ArrayList<String> list = new ArrayList<String>();
  23. Class cls = o.getClass();
  24. Field[] fields = cls.getDeclaredFields();
  25. for (Field f : fields) {
  26. f.setAccessible(true);
  27. if (f.get(o) != null && f.get(o) != "") {
  28. list.add(f.getName() + "=" + f.get(o) + "&");
  29. }
  30. }
  31. int size = list.size();
  32. String [] arrayToSort = list.toArray(new String[size]);
  33. Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
  34. StringBuilder sb = new StringBuilder();
  35. for(int i = 0; i < size; i ++) {
  36. sb.append(arrayToSort[i]);
  37. }
  38. String result = sb.toString();
  39. result += "key=" + Configure.getKey();
  40. Util.log("Sign Before MD5:" + result);
  41. result = MD5.MD5Encode(result).toUpperCase();
  42. Util.log("Sign Result:" + result);
  43. return result;
  44. }
  45. public static String getSign(Map<String,Object> map){
  46. ArrayList<String> list = new ArrayList<String>();
  47. for(Map.Entry<String,Object> entry:map.entrySet()){
  48. if(entry.getValue()!=""){
  49. list.add(entry.getKey() + "=" + entry.getValue().toString().trim() + "&");
  50. }
  51. }
  52. int size = list.size();
  53. String [] arrayToSort = list.toArray(new String[size]);
  54. Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
  55. StringBuilder sb = new StringBuilder();
  56. for(int i = 0; i < size; i ++) {
  57. sb.append(arrayToSort[i]);
  58. }
  59. String result = sb.toString();
  60. result += "key=" + Configure.getKey();
  61. Util.log("Sign Before MD5:" + result);
  62. result = MD5.MD5Encode(result).toUpperCase();
  63. Util.log("Sign Result:" + result);
  64. return result;
  65. }
  66. /**
  67. * 从API返回的XML数据里面重新计算一次签名
  68. * @param responseString API返回的XML数据
  69. * @return 新鲜出炉的签名
  70. * @throws ParserConfigurationException
  71. * @throws IOException
  72. * @throws SAXException
  73. */
  74. public static String getSignFromResponseString(String responseString) throws IOException, SAXException, ParserConfigurationException {
  75. Map<String,Object> map = XMLParser.getMapFromXML(responseString);
  76. //清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
  77. map.put("sign","");
  78. //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
  79. return Signature.getSign(map);
  80. }
  81. /**
  82. * 检验API返回的数据里面的签名是否合法,避免数据在传输的过程中被第三方篡改
  83. * @param responseString API返回的XML数据字符串
  84. * @return API签名是否合法
  85. * @throws ParserConfigurationException
  86. * @throws IOException
  87. * @throws SAXException
  88. */
  89. public static boolean checkIsSignValidFromResponseString(String responseString) throws ParserConfigurationException, IOException, SAXException {
  90. Map<String,Object> map = XMLParser.getMapFromXML(responseString);
  91. Util.log(map.toString());
  92. String signFromAPIResponse = map.get("sign").toString();
  93. if(signFromAPIResponse=="" || signFromAPIResponse == null){
  94. Util.log("API返回的数据签名数据不存在,有可能被第三方篡改!!!");
  95. return false;
  96. }
  97. Util.log("服务器回包里面的签名是:" + signFromAPIResponse);
  98. //清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
  99. map.put("sign","");
  100. //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
  101. String signForAPIResponse = Signature.getSign(map);
  102. if(!signForAPIResponse.equals(signFromAPIResponse)){
  103. //签名验不过,表示这个API返回的数据有可能已经被篡改了
  104. Util.log("API返回的数据签名验证不通过,有可能被第三方篡改!!!");
  105. return false;
  106. }
  107. Util.log("恭喜,API返回的数据签名验证通过!!!");
  108. return true;
  109. }
  110. }