Python根据传入参数生成签名

问题描述

Python根据传入参数生成签名




解决方案

nonce:仅一次有效随机字符串,客户端随机生成的值,作为参数传递过来,目的是增加sign签名的多变性。随机值一般是数字和字母的组合。实际使用时可以加上客户端的ip地址,mac地址等信息做个哈希

sign:签名参数,防止参数被非法篡改,最常见的是修改金额等敏感参数。sign的值一般是将所有非空参数按升序排序后+token+key+timestamp+nonce拼接在一起,再使用某种加密算法进行加密,作为接口中的一个参数sign或放在请求头中进行请求。 nonce可用简单随机数

接口在网络传输过程中如果被黑客挟持,并修改其中的参数值,然后再继续调用接口,虽然参数的值被修改了,但是因为黑客不知道sign是如何计算出来的,不知道sign都有哪些值构成,不知道以怎样的顺序拼接在一起的,最重要的是不知道签名字符串中的key是什么,所以黑客可以篡改参数的值,但没法修改sign的值,当服务器调用接口前会按照sign的规则重新计算出sign的值然后和接口传递的sign参数的值做比较,如果相等表示参数值没有被篡改,如果不等,表示参数被非法篡改了,就不执行接口了。




代码

为简略将token、key的参数去除,仅以参数升序+timestamp作加密

构造签名步骤:

  1. 对body升序排序
  2. 固有参数放入body和时间戳
  3. 对固有参数顺序排序
  4. 拼接固有参数得到签名字符串
  5. 加密算法计算签名字符串获得签名
  6. 将签名放入参数或请求头中
  7. 发送请求
import time
import json
import hashlib
import secrets


def sign(body: str, ts: int) -> str:
    '''构造签名

    :param body: 请求参数,JSON字符串
    :param ts: 时间戳,int类型
    :return: 签名字符串

    >>> sign('{"cityname":"苏州","dtype":"1","params":{"format":"1"}}', 1596666666)
    'bcd9e5778bff35f5689c47086895fbca'
    '''
    body = json.loads(body)
    body = {k: body[k] for k in sorted(body)}  # 对键值对排序(顺序)
    body = json.dumps(body, separators=(',', ':'), ensure_ascii=False)  # 转JSON字符串。不允许,和:后有空格

    args = {
        'key': 'Gjb9UH_OTflkGqLdLk-ofN_LF2TVch7xFrNZb1YJX3I',
        'timestamp': ts,
        'body': body
    }  # 固有参数,内容自行决定
    args = {k: args[k] for k in sorted(args)}  # 对键值对排序(顺序)

    sign = '&'.join(['{0}={1}'.format(k, v) for k, v in args.items()])  # 拼接签名字符串
    sign = hashlib.md5(sign.encode('utf-8')).hexdigest()  # md5算法
    return sign


if __name__ == '__main__':
    body = '{"cityname":"苏州","dtype":"1","params":{"format":"1"}}'  # 请求参数
    ts = 1596666666  # 时间戳
    print(sign(body, ts))  # 传入请求参数和时间戳生成签名
    ...  # 做后续请求







参考文献

  1. Java生鲜电商平台-API接口设计之token、timestamp、sign 具体架构与实现
  2. hashlib — 安全哈希与消息摘要
  3. 如何防止重放攻击
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XerCis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值