Валидация initData в веб-приложении Телеграма (Telegram Mini App) на Qt
Телеграм позволяет открыть https-ресурс из приложения, предоставляя механизм для валидации пользователя на стороне веб-сервера. Судя по документации, в валидации ничего сложного нет. Однако при реализации возникло непонимание: мой HMAC-SHA256 хеш всегда отличается. Имею такой код:
const static QByteArray secret = QMessageAuthenticationCode::hash("Мой_токен",
"WebAppData", QCryptographicHash::Sha256).toHex();
const auto initData = reqData.body->value("data").toObject().value("initData");
QUrlQuery query(initData.toString());
QString hash = query.queryItemValue("hash");
const QString originalInitDataString = initData.toString();
qInfo().noquote() << "Original initData:";
qInfo().noquote() << originalInitDataString;
qInfo().noquote() << "";
QStringList initStringList = originalInitDataString.split('&');
initStringList.removeIf([](const QString& str)->bool { return str.startsWith("hash="); });
initStringList.sort();
const QString initString = QByteArray::fromPercentEncoding( initStringList.join('\n').toUtf8() );
qInfo().noquote() << "Init string:\n";
qInfo().noquote() << initString;
qInfo().noquote() << "\ninitStringList size:" << initStringList.size();
const QString myHash1 = QMessageAuthenticationCode::hash(initString.toUtf8(), secret, QCryptographicHash::Sha256).toHex();
qInfo().noquote() << "\nMy hash:" << myHash1;
qInfo().noquote() << "Tg hash:" << hash;
И примерно такой вывод в консоль:
Original initData:
query_id=AAFMntEHAwAAAEye0QdtEbRW&user=%7B%22id%22%3A6573629%2C%22first_name%22%3A%22%D0%A0%D0%BE%D0%BC%D0%B0%D0%BD%22%2C%22last_name%22%3A%22%22%2C%22username%22%3A%22user111%22%2C%22language_code%22%3A%22ru%22%2C%22is_premium%22%3Atrue%2C%22allows_write_to_pm%22%3Atrue%7D&auth_date=1717189626&hash=c90ab846247bcaa3339911ac39272823eead4218a6e8ca7bb358ce85d6038275
Init string:
auth_date=1717189626
query_id=AAFMntEHAwAAAEye0QdtEbRW
user={"id":6573629,"first_name":"Роман","last_name":"","username":"user111","language_code":"ru","is_premium":true,"allows_write_to_pm":true}
initStringList size: 3
My hash: 0898cff38a65ff1c253145b068b7cda562e5392e1f02abcab50c81680103e9c9
Tg hash: c90ab846247bcaa3339911ac39272823eead4218a6e8ca7bb358ce85d6038275
Грешил на декодирование текста из url-encoded. Перепробовал все варианты, которые предоставляет Qt (fully decoded, encode urf-8 и прочее).
Есть ли у кого-то опыт или интуитивные соображения о том, что в этом коде делается неверно?
Ответы (1 шт):
Автор решения: mynameiskostya
→ Ссылка
Ошибка была в формировании secret:
const static QByteArray secret = QMessageAuthenticationCode::hash("Мой_токен", "WebAppData", QCryptographicHash::Sha256);
Ключ нужен в бинарном формате, НЕ в хексе.