为了保证http请求数据的安全性,防篡改性以及用于标示机构身份,防止伪造的接口请求。
一、MD5算Hash方式:
加密规则可以根据双方接口协商定义,示例如下:
1. 参数说明
接口协议中通常会提供一个 appKey作为唯一的标识。appSecret作为接入密钥。
例如:
appkey=heheda
appSecret=39ertfefdsg406c7c36592d42022aaecc(简单的可以是base64转换一下即可,作用:用于机构验证推送请求参数中的hash)
请求路径:
http://www.heheda.com/login
请求参数
appKey 合作方平台标识
name 用户名
idcard 识别号
phone 手机号
time Unix时间戳
sign 签名串
2. 加密规则
(1)将筛选的参数按照第一个字符的键值ASCII码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值ASCII码递增排序,以此类推。
(2)将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用&字符连接起来,此时生成的字符串为待签名字符串
(3)生成签名:sign = md5(待签名字符串)
参数列表为:
appKey=1heheda,
name=2呵呵哒
idcard=3666666
phone=42365247895
time=5234567891
待签名字符串为(取排序后的结果,这里私钥appSecret不参与排序):
appKey=1heheda&name=2呵呵哒&idcard=3666666&phone=42365247895&time=5234567891
》》生成签名 sign = md5(appKey=1heheda&name=2呵呵哒&idcard=3666666&phone=42365247895&time=5234567891)
3. 处理流程
我们根据加密要求,把要传送的字段进行排序和MD5加密生成数字签名。将加密后的结果和传输的字段一并送过去。
appKey=1heheda&name=2呵呵哒&idcard=3666666&phone=42365247895&time=5234567891&&appSecret=密钥&sign=签名串。
4.验证方式
如何保证这条http请求能够正常请求相应数据呢?
提供接口方,也是根据传输的字段(appKey=1heheda&name=2呵呵哒&idcard=3666666&phone=42365247895&time=5234567891)进行排序和MD5加密(根据appSecret=密钥)。将加密后的结果verifySign(服务方)与sign(请求方)进行比较。如果相同,就说明是一个正常的请求。反之,就是以非法请求。
核心代码Md5Util
.
/**md5哈希处理参数
* @param param 参数列表
* @param orgSecretKey 机构API私钥
*/
public static Map<String, String> hash(Map<String, String> param,String orgSecretKey) {
StringBuilder sb = new StringBuilder();
Iterator iterator = param.keySet().iterator();
while (iterator.hasNext()) {
sb.append(param.get(iterator.next()));
}
param.put("hash", md5(sb.toString() + orgSecretKey, "UTF-8").toUpperCase());
return param;
}
/**
* md5
* @param msg
* @param charset
* @return
*/
public static String md5(String msg, String charset) {
try {
System.out.println("md5Src:" + msg);
MessageDigest digest = MessageDigest.getInstance("md5");
byte[] hashedBytes = digest.digest(msg.getBytes(charset));
String rst = byts2hexstr(hashedBytes);
System.out.println("md5:" + rst.toUpperCase()