API接口签名规范

背景:为了增加接口参数安全,对接口参数加盐进行签名校验。

原理:客户端对传送的参数字典排序后,进行md5签名。服务器接收参数后,同理进行参数字典排序后md5签名。若客户端与服务端的签名一致,说明参数未被篡改,校验通过。

请求参数示例:

字段数据类型描述
phone158112341234String手机号
timestamp1538990392850long时间戳
deviceIdmo-231odvepqdString设备id
sign158112341234String接口签名,md5(参数字典排序后加盐)

注:
1.参数排序时,不包括sign参数
2.加盐参数使用desKey,放在参数字典排序后的开头位置
3.遇到数值拼接时,需统一转换成字符串类型。如:123 需转换成 “123”
4.为避免客户端和服务器端签名对null处理不一致,若参数值为null时,请转换成空字符串("")

签名步骤
1.字段字典排序:
deviceId phone timestamp
2.参数拼接:
mo-231odvepqd1581123412341538990392850

3.加盐:
hechaojie.commo-231odvepqd1581123412341538990392850

这里加盐参数为:hechaojie.com,请注意安全存储。

4.md5签名:
21bf08491dbf4013a8e9275f1d603e4a

客户端发送数据示例:

{"phone":"158112341234","sign":"21bf08491dbf4013a8e9275f1d603e4a","deviceId":"mo-231odvepqd","timestamp":1538990392850}

服务器签名工具类示例:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;
import cn.hechaojie.common.core.encryption.MD5;
import cn.hechaojie.common.core.util.Constant;
/**
 * 接口签名工具类
 * @author hecj
 *
 */
public class SignKit {
     
    // 签名字段
    final static String SIGN_FIELD = "sign";
    /**
     * 签名
     * @param signObj
     * @return
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static String sign(Object obj) {
        if(obj instanceof Map) {
            return MD5.md5crypt(getDictStr((Map)obj));
        }
        if(obj instanceof JSONObject) {
            return MD5.md5crypt(getDictStr((JSONObject)obj));
        }
        throw new RuntimeException("暂时不支持此类型生成签名,"+obj.getClass());
    }
     
    /**
    * JSONObject字段排序拼接
    */
    public static String getDictStr(JSONObject obj) {
        List<String> keys = new ArrayList<String>(obj.keySet());
        keys.remove(SIGN_FIELD);
        Collections.sort(keys);
        StringBuffer str = new StringBuffer(Constant.ApiDesKey);
        for(String key : keys) {
            Object value = obj.get(key);
            if(value == null) {
                value = "";
            }
            str.append(String.valueOf(value));
        }
        return str.toString();
    }
     
    public static String getDictStr(Map<String,Object> obj) {
        List<String> keys = new ArrayList<String>(obj.keySet());
        keys.remove(SIGN_FIELD);
        Collections.sort(keys);
        StringBuffer str = new StringBuffer(Constant.ApiDesKey);
        for(String key : keys) {
            Object value = obj.get(key);
            if(value == null) {
                value = "";
            }
            str.append(String.valueOf(value));
        }
        return str.toString();
    }
}

注:仅供参考,有更好的方案可@我,共同探讨。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值