本文目录导读:

我来为您介绍Python中生成接口签名的常见方法,这里以几种典型的签名算法为例:
HMAC-SHA256 签名(最常用)
import hashlib
import hmac
import time
import json
class APISignature:
def __init__(self, secret_key):
self.secret_key = secret_key
def generate_signature(self, params, timestamp=None):
"""
生成HMAC-SHA256签名
:param params: 请求参数字典
:param timestamp: 时间戳(可选)
:return: 签名字符串
"""
if timestamp is None:
timestamp = int(time.time())
# 1. 参数排序(按key排序)
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 2. 拼接参数字符串
param_str = '&'.join([f"{k}={v}" for k, v in sorted_params])
# 3. 添加时间戳和密钥
sign_str = f"{param_str}×tamp={timestamp}&key={self.secret_key}"
# 4. 生成签名
signature = hmac.new(
self.secret_key.encode('utf-8'),
sign_str.encode('utf-8'),
hashlib.sha256
).hexdigest().upper()
return signature, timestamp
# 使用示例
def api_request_example():
# 初始化签名器
secret_key = "your_secret_key_here"
signer = APISignature(secret_key)
# 请求参数
params = {
"app_id": "test_app",
"method": "get_user_info",
"user_id": "12345",
"version": "1.0"
}
# 生成签名
signature, timestamp = signer.generate_signature(params)
print(f"签名: {signature}")
print(f"时间戳: {timestamp}")
# 构造完整请求参数
request_params = params.copy()
request_params['timestamp'] = timestamp
request_params['sign'] = signature
return request_params
MD5签名(传统方式)
import hashlib
import time
class MD5Signature:
def __init__(self, app_secret):
self.app_secret = app_secret
def generate_signature(self, params):
"""
生成MD5签名
"""
# 1. 移除sign参数(如果有)
params.pop('sign', None)
# 2. 按key排序
sorted_keys = sorted(params.keys())
# 3. 拼接字符串
sign_str = self.app_secret
for key in sorted_keys:
sign_str += f"{key}{params[key]}"
sign_str += self.app_secret
# 4. MD5加密
signature = hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()
return signature
# 使用示例
def md5_sign_example():
app_secret = "your_app_secret"
signer = MD5Signature(app_secret)
params = {
"name": "张三",
"age": 25,
"timestamp": int(time.time())
}
signature = signer.generate_signature(params)
params['sign'] = signature
print(f"参数: {params}")
print(f"签名: {signature}")
RSA签名(更安全)
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
import base64
class RSASignature:
def __init__(self, private_key_path):
with open(private_key_path, 'r') as f:
self.private_key = RSA.import_key(f.read())
def generate_signature(self, data):
"""
生成RSA签名
"""
# 1. 将数据转换为字符串
if isinstance(data, dict):
# 排序后转为JSON
sorted_data = dict(sorted(data.items()))
message = json.dumps(sorted_data, separators=(',', ':'))
else:
message = str(data)
# 2. 计算哈希
hash_obj = SHA256.new(message.encode('utf-8'))
# 3. 生成签名
signer = PKCS1_v1_5.new(self.private_key)
signature = signer.sign(hash_obj)
# 4. Base64编码
return base64.b64encode(signature).decode('utf-8')
# 使用示例
def rsa_sign_example():
signer = RSASignature("private_key.pem")
params = {
"order_id": "20231201001",
"amount": 100.50,
"currency": "CNY"
}
signature = signer.generate_signature(params)
print(f"RSA签名: {signature}")
完整的客户端-服务端签名验证示例
import hashlib
import hmac
import time
import json
from flask import Flask, request, jsonify
# ============== 客户端 ==============
class APIClient:
def __init__(self, app_key, app_secret, base_url):
self.app_key = app_key
self.app_secret = app_secret
self.base_url = base_url
def generate_signature(self, params):
"""生成签名"""
# 基础参数
params['app_key'] = self.app_key
params['timestamp'] = int(time.time())
params['nonce'] = str(time.time_ns()) # 随机字符串
# 排序并拼接
sorted_keys = sorted(params.keys())
sign_str = self.app_secret
for key in sorted_keys:
sign_str += f"{key}{params[key]}"
sign_str += self.app_secret
# 生成签名
params['sign'] = hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()
return params
def send_request(self, endpoint, data=None):
"""发送API请求"""
import requests
params = data or {}
signed_params = self.generate_signature(params)
response = requests.post(
f"{self.base_url}{endpoint}",
json=signed_params
)
return response.json()
# ============== 服务端 ==============
app = Flask(__name__)
# 存储应用密钥(实际使用时应该从数据库获取)
APP_SECRETS = {
"test_app": "test_secret_key"
}
@app.route('/api/verify', methods=['POST'])
def verify_api_request():
"""验证API请求签名"""
data = request.get_json()
# 获取必要参数
app_key = data.get('app_key')
timestamp = data.get('timestamp')
nonce = data.get('nonce')
client_sign = data.get('sign')
# 验证参数完整性
if not all([app_key, timestamp, nonce, client_sign]):
return jsonify({"error": "Missing required parameters"}), 400
# 获取服务端密钥
server_secret = APP_SECRETS.get(app_key)
if not server_secret:
return jsonify({"error": "Invalid app_key"}), 401
# 验证时间戳(防止重放攻击)
current_time = int(time.time())
if abs(current_time - int(timestamp)) > 300: # 5分钟有效期
return jsonify({"error": "Request expired"}), 401
# 验证签名
# 移除sign参数,重新生成签名
verify_data = data.copy()
verify_data.pop('sign')
# 按客户端相同的方式生成签名
sorted_keys = sorted(verify_data.keys())
sign_str = server_secret
for key in sorted_keys:
sign_str += f"{key}{verify_data[key]}"
sign_str += server_secret
server_sign = hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()
if server_sign != client_sign:
return jsonify({"error": "Invalid signature"}), 401
return jsonify({"message": "Signature verification passed", "data": data})
if __name__ == '__main__':
app.run(debug=True)
常用的签名规范总结
签名步骤
- 参数排序:按参数名的字典序排序
- 拼接字符串:将排序后的参数按
key=value格式拼接 - 添加密钥:在拼接字符串前后添加密钥
- 加密生成:使用MD5、SHA256等算法加密
- 返回结果:通常转成大写16进制字符串
最佳实践建议
class BestPracticeSignature:
"""签名最佳实践"""
@staticmethod
def generate(params, secret_key, version='v2'):
"""生成签名"""
# 1. 移除空值和sign参数
params = {k: v for k, v in params.items()
if v is not None and k != 'sign'}
# 2. 添加必需参数
params.setdefault('timestamp', int(time.time()))
params.setdefault('nonce', str(uuid.uuid4().hex[:16]))
params.setdefault('version', version)
# 3. 参数排序
sorted_params = sorted(params.items())
# 4. 拼接签名串
sign_parts = []
for key, value in sorted_params:
if isinstance(value, dict):
value = json.dumps(value, separators=(',', ':'))
sign_parts.append(f"{key}={value}")
sign_str = '&'.join(sign_parts)
sign_str = f"{secret_key}{sign_str}{secret_key}"
# 5. 生成签名
signature = hashlib.md5(sign_str.encode()).hexdigest().upper()
return signature, params
# 使用示例
def main():
# 准备参数
params = {
"method": "user.info",
"uid": 1001,
"name": "测试用户"
}
# 生成签名
signature, signed_params = BestPracticeSignature.generate(
params,
"your_secret_key"
)
signed_params['sign'] = signature
print(f"签名后的请求参数:\n{json.dumps(signed_params, indent=2)}")
这些签名方法的选择取决于您的具体需求:
- HMAC-SHA256:最常用,安全性高
- MD5:简单快速,适合对安全性要求不高的场景
- RSA:最安全,但需要管理密钥对
实际使用时,建议根据API文档选择合适的签名算法。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播