python hmac库的使用记录(Telegram小程序hash生成)
2025-02-08 10:15 第二个卿老师 阅读(17) 评论(0) 编辑 收藏 举报最近要测试Telegram小程序,发现登录接口需要传验证hash,如下图
阅读开发文档:https://core.telegram.org/bots/webapps#webappchat,中文翻译截图如下
根据上述说明,请求body中initData字段是包含了用户信息的数据校验字符串,需要按照字母顺序排序。而hash就是这个数据校验字符串使用HMAC-SHA-256加密方法,秘钥也是使用HMAC-SHA-256加密生成的(由bot_token与WebAPPData常量生成,bot_token是申请TG小程序的令牌)。
以下是JS的hash生成代码:
const TELEGRAM_BOT_TOKEN = "74xxxxx:AAG1nyHS8eSUxxxxxx; const CryptoJS = require("crypto-js"); const telegramInitData = "user=%7B%22id%22%3A6648829924%2C%22first_name%22%3A%22Mu%22%2C%22last_name%22%3A%22Mu%22%2C%22language_code%22%3A%22zh-hans%22%2C%22allows_write_to_pm%22%3Atrue%7D&chat_instance=-88490054829990738&chat_type=sender&auth_date=1721033518&hash=7fd6c890ee7323000d169b87c4bb7a3635c263f8016331fcefff5b73ab3c9ce5"; const initData = new URLSearchParams(telegramInitData); const hash = initData.get("hash"); let dataToCheck = []; initData.sort(); initData.forEach( (val, key) => key !== "hash" && dataToCheck.push(`${key}=${val}`), ); const secret = CryptoJS.HmacSHA256(TELEGRAM_BOT_TOKEN, "WebAppData"); const _hash = CryptoJS.HmacSHA256(dataToCheck.join("\n"), secret).toString( CryptoJS.enc.Hex, ); console.log(_hash, hash, _hash == hash);
这是python的hash生成代码
import hmac
import hashlib
from urllib.parse import unquote
import urllib.parse
import json
def generate_hash(init_data, token, c_str="WebAppData"):
# 解码并过滤初始化数据,去除包含 hash= 的部分,并按键名排序
init_data = sorted([chunk.split("=")
for chunk in unquote(init_data).split("&")
if chunk[:len("hash=")] != "hash="],
key=lambda x: x[0])
# 将处理后的数据重新格式化为字符串。
init_data = "\n".join([f"{rec[0]}={rec[1]}" for rec in init_data])
# 使用"WebAppData"作为秘钥生成新秘钥
secret_key = hmac.new(c_str.encode(), token.encode(),
hashlib.sha256).digest()
# 使用新秘钥生成hash
data_check = hmac.new(secret_key, init_data.encode(),
hashlib.sha256)
return data_check.hexdigest()
if __name__ == '__main__':
token = '74xxxxx:AAG1nyHS8eSUxxxxxx' # bot_token
user = {
"id": 666666,
"first_name": "M",
"last_name": "M",
"language_code": "zh-hans",
"allows_write_to_pm": True,
"is_premium": True, # tg 会员
}
# 对user进行URL编码
encoded_user = urllib.parse.quote((json.dumps(user)))
# 拼接其他信息
init_data_demo = 'user='+encoded_user+'&chat_instance=-88490054829990738&chat_type=sender&auth_date=1721033518'
# 生成拼接后字符串的hash
hash_str = generate_hash(init_data_demo, token)
print("hash:", hash_str)
# 生成请求body的initData数据
init_data = init_data_demo + "&hash=" + hash_str
print("init_data:", init_data)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2022-02-08 python基础练习题(题目 取一个整数a从右端开始的4〜7位。)