一文搞懂接口参数签名与验签(附含java python php版)
更新时间:2023年06月12日 10:23:39 作者:波波
这篇文章主要为大家介绍了java python php不同版的接口参数签名与验签示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
引言
随着前后端分离的开发模式的发展,接口安全显得越来越重要。我们通常的做法是为接口的请求参数进行加密,也就是我们常说的“签名与验签”。希望本篇笔记能帮助部分需要的小伙伴们。
说在前面:安全的方法不能局限于此!!!本篇笔记仅供参考学习。
签名步骤
既然要签名(加密),那么我们一定要有自己的加密方法。以下为示例的加密步骤。
- 将所有的参数进行字典排序;
- 将排序后的数组key与value用“&”符号连接。生成类似Get请求的参数格式。如:
tel=15588888888&passwd=123456×tamp=165031031
- 将第二步生成的字符串参数进行MD5加密;
- 将第三步生成的签名转换为大写;
签名方法(PHP版)
/** * Sign签名方法 * @param array $param 待签名的参数 * @param string $key 请求方Key * @return string 签名 * @throws \think\Exception */ function generateToken(array $param,string $key=''):string{ if(emptyempty($param)) throw new \think\Exception('参数不能为空'); ksort($param); if (isset($param['sign'])) unset($param['sign']); foreach ($param as $k => $v) { if ('' === $v || null === $v) continue; $buff .= "{$k}={$v}&"; } $buff .= ("key=" . $key); return strtoupper(md5($buff)); }
参数说明:
$param
请求主体参数,数组形式,不包含Key;$key
为了安全起见建议将Key放在请求的Header部分,具体键值双方约定即可,常见的是放入Hrader部分的Authorization
、App-Key
等;
签名验证
签名的验证非常简单,只需一行代码判断请求体中的Sign签名与签名结果是否一致即可。示例如下:
- var_dump($param['sign'] == generateToken($param,$key));
- //返回布尔类型true或false
其他语言拓展:
1、Java版签名加密方法
import java.util.Map; import java.util.TreeMap; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class SignUtil { /** * Sign签名方法 * * @param param 待签名的参数 * @param key 请求方Key * @return 签名 * @throws Exception */ public static String generateToken(Map<String, String> param, String key) throws Exception { if (param.isEmpty()) { throw new Exception("参数不能为空"); } // 将参数按照ASCII码从小到大排序 Map<String, String> sortedParam = new TreeMap<>(param); // 拼接参数 StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String> entry : sortedParam.entrySet()) { String k = entry.getKey(); String v = entry.getValue(); if (v != null && !v.equals("")) { sb.append(k).append("=").append(v).append("&"); } } sb.append("key=").append(key); // 计算MD5签名 return getMD5(sb.toString()).toUpperCase(); } /** * 计算MD5签名 * * @param str 待签名的原始字符串 * @return MD5签名 * @throws NoSuchAlgorithmException */ private static String getMD5(String str) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] bytes = md.digest(str.getBytes()); StringBuilder sb = new StringBuilder(); for (byte b : bytes) { String hex = Integer.toHexString(b & 0xff); if (hex.length() == 1) { sb.append("0"); } sb.append(hex); } return sb.toString(); } }
2、Python版签名加密方法
import hashlib def generateToken(param: dict, key: str) -> str: if not param: raise Exception('参数不能为空') # 将参数按照ASCII码从小到大排序 sortedParam = dict(sorted(param.items())) # 拼接参数 buff = '' for k, v in sortedParam.items(): if v is not None and v != '': buff += f'{k}={v}&' buff += f'key={key}' # 计算MD5签名 return hashlib.md5(buff.encode('utf-8')).hexdigest().upper()
以上就是一文搞懂接口参数签名与验签(附含java python php版)的详细内容,更多关于接口参数签名验签的资料请关注脚本之家其它相关文章!
最新评论