Skip to content

Instantly share code, notes, and snippets.

@altbodhi
Created March 27, 2025 14:22
Show Gist options
  • Save altbodhi/b303730eb91fc16fb078b16f1ffda8f3 to your computer and use it in GitHub Desktop.
Save altbodhi/b303730eb91fc16fb078b16f1ffda8f3 to your computer and use it in GitHub Desktop.
Check hash initData TelegramWebApp
module TelegramWebApp =
open System.Security.Cryptography
open System.Text
open System.Web
let validateInitData botToken (initData: string) =
let items =
initData.Split "&" |> Array.map (fun x -> let p = x.Split("=") in (p[0], p[1]))
let hashData = items |> Array.find (fun x -> fst x = "hash")
let decode = HttpUtility.UrlDecode
let xs =
items
|> Array.filter (fun x -> x <> hashData)
|> Array.map (fun (k, v) -> $"{k}={(decode v)}")
|> Array.sort
|> String.concat "\n"
let bytes (str: string) = Encoding.Default.GetBytes str
let secret = HMACSHA256.HashData(bytes "WebAppData", bytes botToken)
let hash (secret_key: byte array) (data: byte array) =
HMACSHA256.HashData(secret_key, data)
|> Array.map (fun b -> b.ToString("x2"))
|> String.concat ""
let origin = snd hashData
let computed = hash secret (bytes xs)
origin = computed
(*
test data from https://docs.telegram-mini-apps.com/platform/init-data
let botToken = "5768337691:AAH5YkoiEuPk8-FZa32hStHTqXiLPtAEhx8"
let initData =
"query_id=AAHdF6IQAAAAAN0XohDhrOrc&user=%7B%22id%22%3A279058397%2C%22first_name%22%3A%22Vladislav%22%2C%22last_name%22%3A%22Kibenko%22%2C%22username%22%3A%22vdkfrost%22%2C%22language_code%22%3A%22ru%22%2C%22is_premium%22%3Atrue%7D&auth_date=1662771648&hash=c501b71e775f74ce10e377dea85a7ea24ecd640b223ea86dfe453e0eaed2e2b2"
let checkData = TelegramWebApp.validateInitData botToken
let valid = checkData initData
assert valid (* only in debug mode! *)
*)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment