Files
smsweb/sign_verify.py
OpenClaw Agent 4e5e93660d Initial commit: SMS Receiver Web Service
Features:
- Receive SMS from TranspondSms Android APP
- HMAC-SHA256 signature verification (optional)
- SQLite database storage
- Web UI with login authentication
- Multiple API tokens support
- Timezone conversion (Asia/Shanghai)
- Search, filter, and statistics
- Auto refresh and session management

Tech Stack:
- Flask 3.0
- SQLite database
- HTML5/CSS3 responsive design
2026-02-06 23:23:49 +00:00

119 lines
3.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
签名验证工具
参考 TranspondSms 的签名规则:
timestamp + "\n" + secret -> HMAC-SHA256 -> Base64 -> URL Encode
"""
import hmac
import hashlib
import base64
import urllib.parse
import time
def generate_sign(secret: str, timestamp: int = None) -> str:
"""
生成签名
Args:
secret: 密钥
timestamp: 时间戳(毫秒),不传则使用当前时间
Returns:
签名字符串
"""
if timestamp is None:
timestamp = int(time.time() * 1000)
string_to_sign = f"{timestamp}\n{secret}"
hmac_code = hmac.new(
secret.encode('utf-8'),
string_to_sign.encode('utf-8'),
digestmod=hashlib.sha256
).digest()
sign = urllib.parse.quote(base64.b64encode(hmac_code).decode())
return sign
def verify_sign(secret: str, sign: str, timestamp: int, max_age: int = 3600000) -> tuple[bool, str]:
"""
验证签名
Args:
secret: 密钥
sign: 待验证的签名
timestamp: 时间戳(毫秒)
max_age: 签名最大有效时间毫秒默认1小时
Returns:
(是否有效, 错误信息)
"""
current_time = int(time.time() * 1000)
# 检查时间戳是否过期
if abs(current_time - timestamp) > max_age:
return False, f"签名过期,时间差: {abs(current_time - timestamp) / 1000:.1f}"
# 生成期望的签名
expected_sign = generate_sign(secret, timestamp)
# 比较签名
if sign != expected_sign:
return False, "签名不匹配"
return True, "签名有效"
def verify_from_app(from_number: str, content: str, timestamp: int,
sign: str, secret: str, max_age: int = 3600000) -> tuple[bool, str]:
"""
验证 TranspondSms APP 发来的请求
Args:
from_number: 发送方手机号
content: 短信内容
timestamp: 时间戳
sign: 签名
secret: 密钥
max_age: 最大有效时间(毫秒)
Returns:
(是否有效, 错误信息)
"""
# 检查必填字段
if not from_number or not content:
return False, "缺少必填字段"
# 如果没有签名,跳过验证(取决于配置)
if not sign:
return True, "无签名,跳过验证"
return verify_sign(secret, sign, timestamp, max_age)
# 测试代码
if __name__ == '__main__':
# 测试签名生成和验证
secret = "test_secret"
timestamp = int(time.time() * 1000)
# 生成签名
sign = generate_sign(secret, timestamp)
print(f"Timestamp: {timestamp}")
print(f"Sign: {sign}")
# 验证签名
is_valid, message = verify_sign(secret, sign, timestamp)
print(f"验证结果: {is_valid}, {message}")
# 测试过期签名
old_timestamp = timestamp - 7200000 # 2小时前
is_valid, message = verify_sign(secret, sign, old_timestamp)
print(f"过期验证: {is_valid}, {message}")
# 测试错误签名
wrong_sign = "wrong_signature"
is_valid, message = verify_sign(secret, wrong_sign, timestamp)
print(f"错误签名: {is_valid}, {message}")