0

I am new to using Telegram and I'm trying to validate the hash provided by Telegram's initData for a webapp mini app (not the login widget) in Java, using the steps from the official Telegram documentation and this guide: Telegram authentication in Spring Boot app

Despite following all guidelines, the calculated hash never matches the hash received from Telegram. According to Telegram’s official documentation, the data-check string for login is constructed by concatenating all received fields (except the hash itself), sorted in alphabetical order, with each key= pair separated by a newline (\n) core.telegram.org, which is what I have done.

What I did:

Using Telegram Mini App (WebApp) via window.Telegram.WebApp.initDataUnsafe

Hash received is something like:

{
  "id": 785xxxxxx,
  "first_name": "xxxxxxx",
  "last_name": "xxxxxx",
  "language_code": "en",
  "allows_write_to_pm": true,
  "photo_url": "https://t.me/i/userpic/320/abc123.svg",
  "auth_date": "1750072455",
  "hash": "a55cdfdexxxxxx"
}

My Java validation code:

public static boolean isValid(Map<String, String> authData, String botToken) {
    String receivedHash = authData.get("hash");
    authData.remove("hash");

    // Step 1: Build data_check_string
    Map<String, String> sorted = new TreeMap<>(authData);
    String dataCheckString = sorted.entrySet().stream()
        .map(e -> e.getKey() + "=" + e.getValue())
        .collect(Collectors.joining("\n"));

    try {
        // Step 2: Generate secret key (HMAC_SHA256 of bot token using "WebAppData")
        Mac mac1 = Mac.getInstance("HmacSHA256");
        mac1.init(new SecretKeySpec("WebAppData".getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] secretKey = mac1.doFinal(botToken.getBytes(StandardCharsets.UTF_8));

        // Step 3: HMAC_SHA256 of dataCheckString using secretKey
        Mac mac2 = Mac.getInstance("HmacSHA256");
        mac2.init(new SecretKeySpec(secretKey, "HmacSHA256"));
        byte[] hmac = mac2.doFinal(dataCheckString.getBytes(StandardCharsets.UTF_8));

        String calculatedHash = bytesToHex(hmac);

        System.out.println("DataCheckString: " + dataCheckString);
        System.out.println("Expected Hash: " + receivedHash);
        System.out.println("Calculated Hash: " + calculatedHash);

        return calculatedHash.equalsIgnoreCase(receivedHash);
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

What I’ve tried:

  • Ensured no extra newline or space characters in dataCheckString

  • Matched PHP logic (which works fine)

  • Used both SHA256(botToken) and HMAC_SHA256(botToken, "WebAppData") as secret

  • Verified same ordering of keys and value formatting

Still facing:

Mismatch between calculated hash and Telegram's received hash for every input.

How can I succesfully verify the hash from initDataUnsafe in Java (with Telegram webapp)? Please help me identify why I am not able to produce the same hash value.

2
  • Your key derivation doesn't match how it's done in the article. Are you sure you should use HmacSHA256 for the key instead of plain SHA-256 like in the article? Commented Jun 20 at 8:04
  • 1
    Hi @MarkRotteveel I have tried that as well. Tried several scenarios. None was working. Above was what mentioned in the telegram documentation core.telegram.org/bots/… Commented Jun 20 at 8:19

1 Answer 1

0

Seem not problem, but we use Telegram.WebApp.initData, you can check what's the difference between 'initData' and 'initDataUnsafe'.

Sign up to request clarification or add additional context in comments.

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.