Reputation: 186
I'm trying to write auth data validation for the Telegram web app (HMAC-SHA256), according to this question: Data validating from Telegram Web App and CryptoJS
I wrote the code in Java:
@Test
public void hmacTest() {
String initData = "[initData]";
List<NameValuePair> params = URLEncodedUtils.parse(initData, Charset.forName("UTF-8"));
List<NameValuePair> preparedData = new java.util.ArrayList<>(params
.stream()
.filter(e -> !e.getName().equals("hash"))
.toList());
preparedData
.sort(Comparator.comparing(NameValuePair::getName));
String dataCheckString = String.join("\n", preparedData
.stream()
.map(e -> e.getName() + "=" + e.getValue())
.toList());
String botToken = "[botToken]";
String botTokenData = "WebAppData";
String hmacSecret = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, botToken).hmacHex(botTokenData);
String calculatedHash = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, hmacSecret).hmacHex(dataCheckString);
String presentedHash = params.get(3).getValue();
boolean result = calculatedHash.equals(presentedHash);
}
However, hash matching fails. Could you please help with the code - what am I doing wrong?
Thanks!
Upvotes: 1
Views: 1091
Reputation: 1
@Jmon it helped a lot. Thanks. I also generated similar code without commomns-codec library.
try {
Mac sha256_hmac = Mac.getInstance("HmacSHA256");
sha256_hmac.init(new SecretKeySpec("WebAppData".getBytes(StandardCharsets.UTF_8),"hmacsha256"));
byte[] hmacSecret = sha256_hmac.doFinal(botToken.getBytes(StandardCharsets.UTF_8));
Mac sha256_hmac1 = Mac.getInstance("HmacSHA256");
sha256_hmac1.init(new SecretKeySpec(hmacSecret ,"HmacSHA256"));
String generatedHash = Hex.encodeHexString(sha256_hmac1.doFinal(dataToCheck.getBytes(StandardCharsets.UTF_8)));
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
//handle exception
}
Upvotes: 0
Reputation: 186
In the end, I solved the problem myself)
Solution:
String botTokenData = "WebAppData";
byte[] hmacSecret = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, botTokenData).hmac(botToken);
String calculatedHash = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, hmacSecret).hmacHex(dataCheckString);
Upvotes: 4