问题背景:
- 如何分辨请求消息是信任渠道商发送的请求?
- 如何分辨请求消息是否被篡改?
从问题背景涉及了两大问题:
- 数据完整性
- 身份认证性
接口签名的定义:
接口签名——API Signature,
接口的请求签名是一种用于确保API请求的完整性和认证性的机制。它通常用于验证请求的身份、防止数据被篡改。
接口签名的原理:
签名验证的核心思想是对API请求进行加密处理,以确保数据的完整性和来源合法性。
当客户端向服务器发送请求时,服务器会根据一定的算法和密钥,对请求中的敏感数据进行加密处理,生成一个签名
。服务器再将这个签名与预先设定的签名进行比对,如果一致,则认为请求合法。
原理解释
流程图:

工作步骤:
-
生成签名:
- 客户端在发送请求时,使用一个密钥(注:秘钥通常是API提供者提供的,怎么安全拿到秘钥不是这里讨论的重点。)对请求的内容进行哈希运算,生成一个签名。
- 签名通常基于请求的部分或全部内容,如:HTTP方法、URL、请求体、时间戳等。
1.1. 参数排序:
将请求参数(如key1=value1&key2=value2)按字典序排序,确保签名的一致性。1.2. 拼接字符串:
将排序后的参数拼接成字符串,例如:key1=value1&key2=value2。(这个排序很重要,位置变换也会导致hash值不一样。)1.3. 添加密钥:
在拼接的字符串末尾加上API密钥(Secret Key),形成待签名字符串。1.4. 生成签名:
使用加密算法(如MAC、HMAC等)对字符串进行加密,生成签名。 -
附加签名:
- 将生成的签名作为请求的一部分发送给服务器。通常是在请求头中添加一个字段,或者在URL中附加签名参数。
-
发送签名:
- 将签名和其他参数一起发送到服务器。
-
服务器验证:
- 服务器接收到请求后,使用相同的秘密密钥和算法步骤(上面的1.1 ~ 1.4 )重新计算签名。
- 比较客户端提供的签名和服务器计算出的签名。如果匹配,则请求被认为是有效的。
问题解决
带着文章开头的问题,结合上面接口签名流程,解释,
- 如何分辨请求消息是信任渠道商发送的请求?
- 如何分辨请求消息是否被篡改?
-
双方约定sign_key作为密钥,该sign_key仅企业和渠道商知道,在传输中不可见,用于参与签名计算。拥有sign_key就等同于是信任关系。(注:sign_key的传输和保存不是本文的重点,虽然这个流程也很重要。)
-
渠道商在发送请求前,将消息内容与sign_key按照规定的签名算法计算出签名。企业在收到请求时,也按相同算法计算出签名。 如果为同一签名,则可信任来源为自己的渠道商,并且内容是完整的。
-
如果非渠道商来源,由于攻击者没有正确的sign_key,无法算出正确的签名;
-
如果消息内容被篡改,由于企业会将接收的消息内容与sign_key重算一次签名,该值与参数的签名不一致,则会拒绝该请求。
上面的问题解决了,但又出现了一个新问题,不能防止重放攻击!
留个思考题吧,请思考一下如何解决这个问题?
浙公网安备 33010602011771号