From e733f61281cf075d8fa5e68a4334b2f912dab430 Mon Sep 17 00:00:00 2001 From: Stas Parshin Date: Tue, 18 Jun 2019 15:29:55 +0700 Subject: [PATCH 1/2] Add Telegram Login auth params checking #167 --- .../telegrambot/login/CheckTelegramAuth.java | 80 +++++++++++++++++++ .../telegrambot/UpdatesListenerTest.java | 2 +- .../login/CheckTelegramAuthTest.java | 25 ++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 library/src/main/java/com/pengrad/telegrambot/login/CheckTelegramAuth.java create mode 100644 library/src/test/java/com/pengrad/telegrambot/login/CheckTelegramAuthTest.java diff --git a/library/src/main/java/com/pengrad/telegrambot/login/CheckTelegramAuth.java b/library/src/main/java/com/pengrad/telegrambot/login/CheckTelegramAuth.java new file mode 100644 index 00000000..87ce1dd9 --- /dev/null +++ b/library/src/main/java/com/pengrad/telegrambot/login/CheckTelegramAuth.java @@ -0,0 +1,80 @@ +package com.pengrad.telegrambot.login; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Date; +import java.util.Iterator; +import java.util.TreeSet; + +/** + * Stas Parshin + * 18 June 2019 + */ +public class CheckTelegramAuth { + + private final String botToken, dataCheck, hash; + private final long authDate; + + public CheckTelegramAuth(String botToken, String authParams) { + String[] params = authParams.split("&"); + TreeSet set = new TreeSet(); + String hash = null; + long authDate = 0; + for (String p : params) { + if (p.startsWith("hash=")) { + hash = p.substring(5); + } else { + set.add(p); + } + if (p.startsWith("auth_date=")) { + authDate = Long.parseLong(p.substring(10)); + } + } + this.hash = hash; + this.authDate = authDate; + this.dataCheck = join(set, "\n"); + this.botToken = botToken; + } + + public Date authDate() { + return new Date(authDate * 1000L); + } + + public boolean isFromTelegram() throws Exception { + String result = hmacSha256(sha256(botToken.getBytes()), dataCheck); + return result.equals(hash); + } + + private byte[] sha256(byte[] string) throws NoSuchAlgorithmException { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + return md.digest(string); + } + + private String hmacSha256(byte[] key, String data) throws NoSuchAlgorithmException, InvalidKeyException { + Mac hmacSha256 = Mac.getInstance("HmacSHA256"); + SecretKeySpec secret_key = new SecretKeySpec(key, "HmacSHA256"); + hmacSha256.init(secret_key); + byte[] result = hmacSha256.doFinal(data.getBytes()); + return hex(result); + } + + public static String hex(byte[] str) { + return String.format("%040x", new BigInteger(1, str)); + } + + public static String join(Iterable elements, CharSequence separator) { + StringBuilder builder = new StringBuilder(); + Iterator it = elements.iterator(); + if (it.hasNext()) { + builder.append(it.next()); + while (it.hasNext()) { + builder.append(separator).append(it.next()); + } + } + return builder.toString(); + } +} diff --git a/library/src/test/java/com/pengrad/telegrambot/UpdatesListenerTest.java b/library/src/test/java/com/pengrad/telegrambot/UpdatesListenerTest.java index 859c606f..2fa478d3 100644 --- a/library/src/test/java/com/pengrad/telegrambot/UpdatesListenerTest.java +++ b/library/src/test/java/com/pengrad/telegrambot/UpdatesListenerTest.java @@ -24,7 +24,7 @@ */ public class UpdatesListenerTest { - private static String token() { + public static String token() { String token; try { Properties properties = new Properties(); diff --git a/library/src/test/java/com/pengrad/telegrambot/login/CheckTelegramAuthTest.java b/library/src/test/java/com/pengrad/telegrambot/login/CheckTelegramAuthTest.java new file mode 100644 index 00000000..c30e73f9 --- /dev/null +++ b/library/src/test/java/com/pengrad/telegrambot/login/CheckTelegramAuthTest.java @@ -0,0 +1,25 @@ +package com.pengrad.telegrambot.login; + +import org.junit.Test; + +import java.util.Date; + +import static com.pengrad.telegrambot.UpdatesListenerTest.token; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Stas Parshin + * 18 June 2019 + */ +public class CheckTelegramAuthTest { + + @Test + public void login() throws Exception { + String data = "id=51314083&first_name=Stas&last_name=Parshin&username=pengrad&photo_url=https://t.me/i/userpic/320/pengrad.jpg&auth_date=1560837746&hash=b00e1b82fdea0718efc02ee645286fbb0c986526dba9b4bb4d51753960feda04"; + CheckTelegramAuth checkTelegramAuth = new CheckTelegramAuth(token(), data); + assertTrue(checkTelegramAuth.isFromTelegram()); + assertEquals(new Date(1560837746000L), checkTelegramAuth.authDate()); + } + +} From b7799635f5feacde7958fc80a93be38bacc46d4d Mon Sep 17 00:00:00 2001 From: Stas Parshin Date: Wed, 19 Jun 2019 12:10:35 +0700 Subject: [PATCH 2/2] Add static factory fromUrl for CheckTelegramAuth --- .../telegrambot/login/CheckTelegramAuth.java | 22 ++++++++++++------- .../login/CheckTelegramAuthTest.java | 4 ++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/library/src/main/java/com/pengrad/telegrambot/login/CheckTelegramAuth.java b/library/src/main/java/com/pengrad/telegrambot/login/CheckTelegramAuth.java index 87ce1dd9..80503233 100644 --- a/library/src/main/java/com/pengrad/telegrambot/login/CheckTelegramAuth.java +++ b/library/src/main/java/com/pengrad/telegrambot/login/CheckTelegramAuth.java @@ -3,6 +3,7 @@ import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.math.BigInteger; +import java.net.URI; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -19,11 +20,15 @@ public class CheckTelegramAuth { private final String botToken, dataCheck, hash; private final long authDate; - public CheckTelegramAuth(String botToken, String authParams) { - String[] params = authParams.split("&"); - TreeSet set = new TreeSet(); + public static CheckTelegramAuth fromUrl(String botToken, String authUrl) { + return new CheckTelegramAuth(botToken, URI.create(authUrl).getQuery()); + } + + private CheckTelegramAuth(String botToken, String authQueryParams) { String hash = null; long authDate = 0; + String[] params = authQueryParams.split("&"); + TreeSet set = new TreeSet(); for (String p : params) { if (p.startsWith("hash=")) { hash = p.substring(5); @@ -45,16 +50,17 @@ public Date authDate() { } public boolean isFromTelegram() throws Exception { - String result = hmacSha256(sha256(botToken.getBytes()), dataCheck); + byte[] secret = sha256(botToken.getBytes()); + String result = hmacSha256(secret, dataCheck); return result.equals(hash); } - private byte[] sha256(byte[] string) throws NoSuchAlgorithmException { + private static byte[] sha256(byte[] string) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("SHA-256"); return md.digest(string); } - private String hmacSha256(byte[] key, String data) throws NoSuchAlgorithmException, InvalidKeyException { + private static String hmacSha256(byte[] key, String data) throws NoSuchAlgorithmException, InvalidKeyException { Mac hmacSha256 = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(key, "HmacSHA256"); hmacSha256.init(secret_key); @@ -62,11 +68,11 @@ private String hmacSha256(byte[] key, String data) throws NoSuchAlgorithmExcepti return hex(result); } - public static String hex(byte[] str) { + private static String hex(byte[] str) { return String.format("%040x", new BigInteger(1, str)); } - public static String join(Iterable elements, CharSequence separator) { + private static String join(Iterable elements, CharSequence separator) { StringBuilder builder = new StringBuilder(); Iterator it = elements.iterator(); if (it.hasNext()) { diff --git a/library/src/test/java/com/pengrad/telegrambot/login/CheckTelegramAuthTest.java b/library/src/test/java/com/pengrad/telegrambot/login/CheckTelegramAuthTest.java index c30e73f9..76077e51 100644 --- a/library/src/test/java/com/pengrad/telegrambot/login/CheckTelegramAuthTest.java +++ b/library/src/test/java/com/pengrad/telegrambot/login/CheckTelegramAuthTest.java @@ -16,8 +16,8 @@ public class CheckTelegramAuthTest { @Test public void login() throws Exception { - String data = "id=51314083&first_name=Stas&last_name=Parshin&username=pengrad&photo_url=https://t.me/i/userpic/320/pengrad.jpg&auth_date=1560837746&hash=b00e1b82fdea0718efc02ee645286fbb0c986526dba9b4bb4d51753960feda04"; - CheckTelegramAuth checkTelegramAuth = new CheckTelegramAuth(token(), data); + String data = "google.com/?id=51314083&first_name=Stas&last_name=Parshin&username=pengrad&photo_url=https://t.me/i/userpic/320/pengrad.jpg&auth_date=1560837746&hash=b00e1b82fdea0718efc02ee645286fbb0c986526dba9b4bb4d51753960feda04"; + CheckTelegramAuth checkTelegramAuth = CheckTelegramAuth.fromUrl(token(), data); assertTrue(checkTelegramAuth.isFromTelegram()); assertEquals(new Date(1560837746000L), checkTelegramAuth.authDate()); }