java web傳輸中的安全簽名
說明:
對請求中的數據 Key對進行簽名,最終生成一個簽名字符串,標記為sign:"djflw8wejwl9w0ejwlush8fw9ew9",位數64位或32位,
服務器端拿到相關數據同樣進行簽名,與客戶端傳入的進行比對,如果簽名不一致,說明請求數據被篡改,根據業務場景進行相應的拒絕。
/**
* 簽名校驗
* @param reqMap
* @param key
* @return
*/
public static boolean check(Map<String, Object> reqMap, String key) {
try {
if (null == reqMap || reqMap.isEmpty())
return false;
log.info("--------------req:{}----------------", reqMap);
Collection<String> keyset = reqMap.keySet();
List<String> list = new ArrayList<String>(keyset);
Collections.sort(list);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
if (!SIGN.equals(list.get(i))) {
Object o = reqMap.get(list.get(i));
if (!ObjectUtils.isEmpty(o)) {
log.debug("key:{}", list.get(i));
String value = o.toString();
if (!isChineseChar(value))
sb.append(value);
}
}
}
log.info("-----------usign text:{}-------------", sb);
if (MD5.md5(sb.toString(), key).equals(reqMap.get(SIGN)))
return true;
} catch (Exception e) {
log.error(e.getMessage(),e);
}
return false;
}
public static boolean isChineseChar (String text){
boolean temp = false;
Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
Matcher m = p.matcher(text);
if (m.find()) {
temp = true;
}
return temp;
}
如傳入的
{
"username":"admin",
"password":"test",
...
}
對username password 對key進行字典排序,再加上某個約定的值,進行md5簽名。 封裝成"sign":"....."傳入后台
后台對所有數據進行同樣的簽名,生成的簽名字符串 與前端傳入的sign值 進行比對。 防止對業務數據進行篡改。
此處的邏輯也可以進行相關的修改,可以對keyvalue&keyvalue&keyvalue&約定的值 具體看業務場景,前后端保持一致即可。