消息签名 hmac库提供了一个new()函数来创建一个新对象来计算消息签名。 8820', bytes(str, 'utf-8'), hashlib.sha1).hexdigest() print(hmac_maker) 运行之后,效果如下: new第1个参数:秘密密钥 第2个参数 :需要认证签名的数据 第3个参数:采用的散列算法 如控制台输出,计算出了一个HMAC签名。 二进制摘要 在许多的Web服务中,我们会经常使用base64编码版本的二进制摘要,所以我们需要将上面的签名数据返回为base64编码的二进制摘要,示例如下: import hashlib import
(2) 不可逆:消息摘要算法的密文无法被解密。 (3) 不需要密钥,可使用于分布式网络。 (4) 无论输入的明文有多长,计算出来的消息摘要的长度总是固定的。 原理 消息摘要,其实就是将需要摘要的数据作为参数,经过哈希函数(Hash)的计算,得到的散列值。 算法实现 MD5、SHA的范例 JDK中使用MD5和SHA这两种消息摘要的方式基本一致,步骤如下: (1) 初始化MessageDigest对象 (2) 更新要计算的内容 (3) 生成摘要 importjava.io.UnsupportedEncodingException 原理 数字签名算法包含签名和验证两项操作,遵循私钥签名,公钥验证的方式。 签名时要使用私钥和待签名数据,验证时则需要公钥、签名值和待签名数据,其核心算法主要是消息摘要算法。 ? 签名 用私钥为消息计算签名 验证 用公钥验证摘要 importjava.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator
它要求调用方按照约定好的算法生成签名字符串,作为请求的一部分,接口提供方验算签名即可知是否合法。 步骤通常如下: 接口提供方给出 appid 和 appsecret 调用方根据 appid 和 appsecret 以及请求参数,按照一定算法生成签名 sign 接口提供方验证签名 生成签名的步骤如下: f=1,b=23,k=33,排序后为 b =23,f=1,k=33,参数名和参数值链接后为 b23f1k33,首尾加上 appsecret 后 md5: md5(secretkey1value1key2value2 在请求中带上时间戳,并且把时间戳也作为签名的一部分,在接口提供方对时间戳进行验证,只允许一定时间范围内的请求,例如 1 分钟。 喜欢(2) 打赏
在一些关键业务接口,系统通常会对请求参数进行签名验证,一旦篡改参数服务端就会提示签名校验失败。在黑盒渗透过程中,如果没办法绕过签名校验,那么就无法进一步深入。 02、MD5签名绕过 业务场景:在一些营销推广的抽奖活动里,关键接口有签名,但没有对单个用户的抽奖次数进行限制。 (3)全局搜索关键字sign,获取签名算法,session+timestamp计算md5,然后md5+nonce重新生成签名。 (2)逆向破解小程序参数签名 将小程序的前端代码复制到本地,Sign值比较长,盲猜RSA签名算法,全局搜索关键字,因关键js代码未作混淆加密,很容易就获取到了RSA签名算法和私钥。 (3)基于jsrsasign的rsa签名验签,尝试篡改请求参数,构建签名计算Sign值。 构建http数据包,成功伪造签名篡改游戏成绩。
接口安全问题 请求身份是否合法? 请求参数是否被篡改? 请求是否唯一? 防止篡改 参数签名 按照请求参数名的字母升序排列非空请求参数(包含AccessKey),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA; 在stringA 实现 请求接口:http://api.test.com/test? Token&AppKey(APP) 在APP开放API接口的设计中,由于大多数接口涉及到用户的个人信息以及产品的敏感数据,所以要对这些接口进行身份验证,为了安全起见让用户暴露的明文密码次数越少越好,然而客户端与服务器的交互在请求之间是无状态的 Token+AppKey签名验证 与上面开发平台的验证方式类似,为客户端分配AppKey(密钥,用于接口加密,不参与传输),将AppKey和所有请求参数组合成源串,根据签名算法生成签名值,发送请求时将签名值一起发送给服务器验证
防止篡改 参数签名 按照请求参数名的字母升序排列非空请求参数(包含AccessKey),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA; 在stringA timestamp+nonce方案 nonce指唯一的随机字符串,用来标识每个被签名的请求。 实现 请求接口:http://api.test.com/test? Token&AppKey(APP) 在APP开放API接口的设计中,由于大多数接口涉及到用户的个人信息以及产品的敏感数据,所以要对这些接口进行身份验证,为了安全起见让用户暴露的明文密码次数越少越好,然而客户端与服务器的交互在请求之间是无状态的 Token+AppKey签名验证 与上面开发平台的验证方式类似,为客户端分配AppKey(密钥,用于接口加密,不参与传输),将AppKey和所有请求参数组合成源串,根据签名算法生成签名值,发送请求时将签名值一起发送给服务器验证
防止篡改 参数签名 按照请求参数名的字母升序排列非空请求参数(包含AccessKey),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA; 在stringA timestamp+nonce方案 nonce指唯一的随机字符串,用来标识每个被签名的请求。 实现 请求接口:http://api.test.com/test? Token&AppKey(APP) 在APP开放API接口的设计中,由于大多数接口涉及到用户的个人信息以及产品的敏感数据,所以要对这些接口进行身份验证,为了安全起见让用户暴露的明文密码次数越少越好,然而客户端与服务器的交互在请求之间是无状态的 Token+AppKey签名验证 与上面开发平台的验证方式类似,为客户端分配AppKey(密钥,用于接口加密,不参与传输),将AppKey和所有请求参数组合成源串,根据签名算法生成签名值,发送请求时将签名值一起发送给服务器验证
# 接口安全问题 请求身份是否合法? 请求参数是否被篡改? 请求是否唯一? # 防止篡改 参数签名 按照请求参数名的字母升序排列非空请求参数(包含AccessKey),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA; 实现 请求接口:http://api.test.com/test? ,由于大多数接口涉及到用户的个人信息以及产品的敏感数据,所以要对这些接口进行身份验证,为了安全起见让用户暴露的明文密码次数越少越好,然而客户端与服务器的交互在请求之间是无状态的,也就是说,当涉及到用户状态时 Token+AppKey签名验证 与上面开发平台的验证方式类似,为客户端分配AppKey(密钥,用于接口加密,不参与传输),将AppKey和所有请求参数组合成源串,根据签名算法生成签名值,发送请求时将签名值一起发送给服务器验证
Java接口签名(Signature)实现方案 大家好,我是程序员田同学! 今天上午收到一个需求,针对当前的系统开发一个对外开放的接口。 既然是对外开放,那么调用者一定没有我们系统的Token,就需要对调用者进行签名验证,签名验证采用主流的验证方式,采用Signature 的方式。 一、要求 下图为具体要求 二、流程 1、线下分配appid和appsecret,针对不同的调用方分配不同的appid和appsecret 2、加入timestamp(时间戳),10分钟内数据有效 针对查询接口,流水号只用于日志落地,便于后期日志核查。 针对办理类接口需校验流水号在有效期内的唯一性,以避免重复请求。 4、加入signature,所有数据的签名信息。 以下代码为接口验证签名的demo实现: //引用jackson依赖 @Autowired private ObjectMapper objectMapper; @Value
Postman是一个非常强大的HTTP接口测试工具,但是最近项目接口升级,为了防止恶意请求,所有的接口都增加了签名的校验。 这样安全性更高,但是在使用Postman自测接口的时候会比较麻烦,每次都需要生成一个临时的签名,而且使用一次之后就会过期。 本文借助Postman的Pre-request Scritp可以实现自动签名功能,每次请求都会生成一个新的签名 代码实现 //签名一般都会使用时间戳,一方面可以生成随机字符串,一方面也用来保证请求的及时性 ["name"] + request.data["age"]; //计算签名(很多项目中的签名,原始字符串还会加入请求参数) let sign = CryptoJS.MD5(str + appid + appId和appSecret 把上述代码写在请求的Pre-request Script,或者Collection中的Pre-request Script(这种方式,可以同时让Collection中的请求全部计算签名
接口签名参数Map字典排序 由于业务需要,需要对请求进行的签名,其中有一部分的算法就是需要对所有参数进行字典排序 /** * 方法用途: 对所有传入参数按照字段名的 ASCII 码从小到大排序 int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) { return (o1.getKey()).toString().compareTo(o2.getKey()); } });
前面我们有讲过如何进行API的安全控制,其中包括数据加密,接口签名等内容。详细可以参考我下面两篇文章: -《前后端API交互如何保证数据安全性》 -《再谈前后端API签名安全?》 在签名部分,通过时间戳的方式来判断当前请求是否有效,目的是为了防止接口被多次使用。但是这样并不能保证每次请求都是一次性的,今天给大家介绍下如何保证请求一次性? 首先我们来回顾一些时间戳判断的原理:客户端每次请求时,都需要进行签名操作,签名中会加上signTime参数(当前请求时间戳)。 HTTP请求从发出到达服务器的正常时间不会很长,当服务器收到HTTP请求之后,首先进行签名检查,通过之后判断时间戳与当前时间相比较,是否超过了一定的时间,这个时间我们可以自行决定要多长,比如1分钟,2分钟都可以 基于nonce的方式可以解决重复使用的问题,最开始知道nonce是在广点通的接口中看到的,如下图所示: ? 1.png 可以看到腾讯这边的接口也是基于时间戳和nonce来控制的。
Java接口签名和验签 import com.alibaba.fastjson.JSON; import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Field ),然后用签名算法进行签名 map.put("sign",""); map.put("class",""); //将API返回的数据根据用签名算法进行计算新的签名 java.security.MessageDigest; public class MD5 { private final static String[] hexDigits = {"0", "1", "2" = b; if (n < 0) { n = 256 + n; } int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } /** * MD5编码 * @param origin
接口签名规则和Java实现签名和验签代码 签名规则 签名生成的通用步骤如下: 第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用 URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。 特别注意以下重要规则: ◆ 参数名ASCII码从小到大排序(字典序); ◆ 如果参数的值为空不参与签名; ◆ 参数名区分大小写; ◆ 验证接口调用传送的sign参数不参与签名,将生成的签名与该sign = b; if (n < 0) { n = 256 + n; } int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } /** * MD5编码 * @param origin
请求的唯一性(不可复制) 二)为了保证数据在通信时的安全性,我们可以采用参数签名的方式来进行相关验证 案例: 我们通过给某 [移动端(app)] 写 [后台接口(api)] 的案例进行分析: 二、MD5参数签名的方式 我们对api查询产品接口进行优化: 1.给app客户端分配对应的key=1、secret秘钥 2.Sign签名,调用API 时需要对请求参数进行签名验证,签名方式如下: 即得到签名Sign 新api接口代码: app调用:http://api.chinasoft.com/getproducts? sign签名,算法和客户端一致 a=2&c=world&b=hello ==》"a=2&b=hello&c=world" ==》secret=123456==》 "a=2&b=hello&c=world type(params[k]) == "number" then tmp[#tmp+1] = k .. "=" .. tostring(params[k]) end end --将salt添加到最后,计算正确的签名
概览 工作中,我们时刻都会和接口打交道,有的是调取他人的接口,有的是为他人提供接口,在这过程中肯定都离不开签名验证。 在设计签名验证的时候,一定要满足以下几点: 可变性:每次的签名必须是不一样的。 时效性:每次请求的时效性,过期作废。 唯一性:每次的签名是唯一的。 完整性:能够对传入数据进行验证,防止篡改。 优点 算法公开、计算量小、加密速度快、加密效率高。 缺点 发送方和接收方必须商定好密钥,然后使双方都能保存好密钥,密钥管理成为双方的负担。 蚂蚁金服,新浪微博 都在使用 RSA2 算法。 常用的接口文档平台: eolinker Apizza Yapi RAP2 DOClever 扩展 一、在 HTTP 和 RPC 的选择上,可能会有一些疑问,RPC框架配置比较复杂,明明用HTTP
概览 工作中,我们时刻都会和接口打交道,有的是调取他人的接口,有的是为他人提供接口,在这过程中肯定都离不开签名验证。 在设计签名验证的时候,一定要满足以下几点: 可变性:每次的签名必须是不一样的。 时效性:每次请求的时效性,过期作废。 唯一性:每次的签名是唯一的。 完整性:能够对传入数据进行验证,防止篡改。 优点 算法公开、计算量小、加密速度快、加密效率高。 缺点 发送方和接收方必须商定好密钥,然后使双方都能保存好密钥,密钥管理成为双方的负担。 蚂蚁金服,新浪微博 都在使用 RSA2 算法。 常用的接口文档平台: eolinker Apizza Yapi RAP2 DOClever 扩展 一、在 HTTP 和 RPC 的选择上,可能会有一些疑问,RPC框架配置比较复杂,明明用HTTP
接口安全问题 请求身份是否合法? 请求参数是否被篡改? 请求是否唯一? 防止篡改 参数签名 按照请求参数名的字母升序排列非空请求参数(包含AccessKey),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA; 在stringA 更多技术干货请关注公众号【Java技术精选】 实现 请求接口:http://api.test.com/test? ,由于大多数接口涉及到用户的个人信息以及产品的敏感数据,所以要对这些接口进行身份验证,为了安全起见让用户暴露的明文密码次数越少越好,然而客户端与服务器的交互在请求之间是无状态的,也就是说,当涉及到用户状态时 Token+AppKey签名验证 与上面开发平台的验证方式类似,为客户端分配AppKey(密钥,用于接口加密,不参与传输),将AppKey和所有请求参数组合成源串,根据签名算法生成签名值,发送请求时将签名值一起发送给服务器验证
开发过程中,我们经常会与接口打交道,有的时候是调取别人网站的接口,有的时候是为他人提供自己网站的接口,但是在这调取的过程中都离不开签名验证。 第2步: 在上一步得到的字符串前面加上验证密钥key(这里的密钥key是接口提供方分配给接口接入方的),然后计算md5值,得到32位字符串,然后转成大写. 第四步,然后将这个字符串进行md5计算,假设得到的是abcdef,然后转为大写,得到ABCDEF这个值即为sign签名值。 注意,计算md5之前请确保接口与接入方的字符串编码一致,如统一使用utf-8编码或者GBK编码,如果编码方式不一致则计算出来的签名会校验失败。 二、签名验证方法: 根据前面描述的签名参数sign生成的方法规则,计算得到参数的签名值,和参数中通知过来的sign对应的参数值进行对比,如果是一致的,那么就校验通过,如果不一致,说明参数被修改过。
接口签名规则及Java代码demo实现 签名规则 签名生成的通用步骤如下: 第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。 特别注意以下重要规则: ◆ 参数名ASCII码从小到大排序(字典序); ◆ 如果参数的值为空不参与签名; ◆ 参数名区分大小写; ◆ 验证接口调用传送的sign参数不参与签名,将生成的签名与该sign ),然后用签名算法进行签名 map.put("sign",""); map.put("class",""); //将API返回的数据根据用签名算法进行计算新的签名 ==","5rWL6K+V5a2X56ym5LiyMg=="]} 16:56:50.089 [main] INFO com.example.utils.Signature - 签名前的map={testBase64Str