skip to Main Content

I have problem with this method in my telegram mini app:
https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app

When client trying to log in into my mini app frontend sends check string like in article, i’m generating hash string on backend to check client log in with this function

import json
import urllib.parse
import hmac
import hashlib

def verify_telegram_webapp_data(telegram_init_data: str, bot_token: str) -> bool:
    init_data = json.loads(urllib.parse.unquote(telegram_init_data))
    if "hash" not in init_data:
        return False

    hash_ = init_data.pop('hash')

    data_to_check_parts = []
    for key, value in sorted(init_data.items()):
        if isinstance(value, dict):
            value = json.dumps(value, separators=(',', ':'), ensure_ascii=False)
        data_to_check_parts.append(f"{key}={value}")
    
    data_to_check = "n".join(data_to_check_parts)

    secret_key = hmac.new(bot_token.encode(), 'WebAppData'.encode(), hashlib.sha256).digest()
    computed_hash = hmac.new(data_to_check.encode(), secret_key, hashlib.sha256).hexdigest()

    print('Data to check:', data_to_check)
    print('Computed hash:', computed_hash)
    print('Provided hash:', hash_)
    
    return computed_hash == hash_

Before telegram added photo_url into their data – this code worked fine, but now it doesn’t work – provided hash and computed hash are different

I’ve tryed to change photo_url, deletу it, but the result is the same…

2

Answers


  1. I ran into the same issue, here’s my code in JS:

     const verifyDataIntegrity = (object, { key, hash }) => {
        // Проверяем, что object является объектом, и что key и hash не пустые
        if (typeof object !== "object" || object === null || !key || !hash)
            throw new Error("Invalid arguments for data integrity verification");
    
        // Сортируем ключи объекта и преобразуем его в строку в формате ключ=значение, разделенные символом новой строки
        const dataCheckString = Object.entries(object).sort().map(([k, v]) => {
            // Если значение является объектом, преобразуем его в строку JSON
            if (typeof v === "object" && v !== null) {
                v = JSON.stringify(v);
            }
    
            // Возвращаем строку в формате ключ=значение
            return `${k}=${v}`;
        }).join("n");
    
        // Создаем хеш из строки для проверки
        const calculatedHash = crypto.createHmac("sha256", key).update(dataCheckString).digest("hex");
    
        // Сравниваем полученный хеш с хешем из данных
        return cryptoUtils.timingSafeEqual(calculatedHash, hash);
    };
    
    Login or Signup to reply.
  2. did you guys fix that?

    const secretKey = Hmac256Util.generateHmac(
    process.env.key,
    ‘WebAppData’,
    );
    const dataHex = Hmac256Util.generateHmac(dataCheckString, secretKey);

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search