猿问

使用带有 Spring Security 的 Telegram 登录

我正在尝试在 Spring Boot 应用程序上实现使用 Telegram 登录(https://core.telegram.org/widgets/login),但遇到了问题。


我一直在尝试实施他们提供的 PHP 代码来验证身份验证,但出了点问题,我无法理解是什么。


所以,这就是 PHP 上的代码


secret_key = SHA256(<bot_token>)

if (hex(HMAC_SHA256(data_check_string, secret_key)) == hash) {

  // data is from Telegram

}

Data-check-string 是所有接收到的字段的串联,按字母顺序排序,格式key=<value>为使用换行符('\n',0xA0)作为分隔符 - 例如,'auth_date=<auth_date>\nfirst_name=<first_name>\nid=<id>\nusername=<username>.


所以,我所做的是:

@AllArgsConstructor

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

public class AuthenticationRequest {


  @NotNull

  private Long authDate;


  private String firstName;


  @NotEmpty

  private String id;


  private String lastName;


  private String photoUrl;


  private String username;


  @NotEmpty

  private String hash;


  @Override

  public String toString() {

    final var data = new StringBuilder();


    for (final Field field : getClass().getDeclaredFields()) {

      try {

        if (!field.getName().equals("hash") && field.get(this) != null) {

          final var fieldName = CaseFormat.LOWER_CAMEL

              .to(CaseFormat.LOWER_UNDERSCORE, field.getName());

          data.append(fieldName).append("=").append(field.get(this)).append("\\n");

        }

      } catch (IllegalAccessException e) {

        e.printStackTrace();

      }

    }


    return data.substring(0, data.length() - 2);

  }

}

还有这两个方法:


private static String hmacSha256(final String data, final byte[] secret) {

    try {

      Mac sha256Hmac = Mac.getInstance("HmacSHA256");

      SecretKeySpec secretKey = new SecretKeySpec(secret, "HmacSHA256");

      sha256Hmac.init(secretKey);


      byte[] signedBytes = sha256Hmac.doFinal(data.getBytes());


      return bytesToHex(signedBytes);

    } catch (NoSuchAlgorithmException | InvalidKeyException ex) {

      return null;

    }

你能告诉我我做错了什么吗?也许我完全误解了验证身份验证数据的方式,或者我错过了什么?


慕桂英3389331
浏览 164回答 2
2回答

蓝山帝景

试试这个,代码有点难看,但效果很好!public boolean verifyAuth(JsonObject Telegram_User){&nbsp; &nbsp; String hash = Telegram_User.remove("hash").getAsString();&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; Mac sha256_HMAC = Mac.getInstance("HmacSHA256");&nbsp; &nbsp; &nbsp; &nbsp; String[] t = Telegram_User.toString().replace("{","").replace("}","").replace("\":","=").replace(",","\n").replace("\"","").split("\n");&nbsp; &nbsp; &nbsp; &nbsp; sha256_HMAC.init(new SecretKeySpec(MessageDigest.getInstance("SHA-256").digest(BezouroBot.telegram.getBotToken().getBytes(StandardCharsets.UTF_8)),"SHA256"));&nbsp; &nbsp; &nbsp; &nbsp; Arrays.sort(t);&nbsp; &nbsp; &nbsp; &nbsp; StringBuilder i = new StringBuilder();&nbsp; &nbsp; &nbsp; &nbsp; boolean First = true;&nbsp; &nbsp; &nbsp; &nbsp; for (String s : t) if(First){ First = false; i = new StringBuilder(s);} else i.append("\n").append(s);&nbsp; &nbsp; &nbsp; &nbsp; return Hex.encodeHexString(sha256_HMAC.doFinal(i.toString().getBytes())).equals(hash);&nbsp; &nbsp; } catch (NoSuchAlgorithmException | InvalidKeyException e) {&nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; }}

慕码人2483693

这是我的工具// define your token to a variableprivate final String TELEGRAM_TOKEN = ""@PostMapping("auth/telegram")public ResponseEntity<Object> telegramAuth(@RequestBody Map<String, Object> request) {&nbsp; &nbsp; String hash = (String) request.get("hash");&nbsp; &nbsp; request.remove("hash");&nbsp; &nbsp; // Prepare the string&nbsp; &nbsp; String str = request.entrySet().stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .sorted((a, b) -> a.getKey().compareToIgnoreCase(b.getKey()))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(kvp -> kvp.getKey() + "=" + kvp.getValue())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.joining("\n"));&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; SecretKeySpec sk = new SecretKeySpec(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Get SHA 256 from telegram token&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MessageDigest.getInstance("SHA-256").digest(TELEGRAM_TOKEN.getBytes(StandardCharsets.UTF_8)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ), "HmacSHA256");&nbsp; &nbsp; &nbsp; &nbsp; Mac mac = Mac.getInstance("HmacSHA256");&nbsp; &nbsp; &nbsp; &nbsp; mac.init(sk);&nbsp; &nbsp; &nbsp; &nbsp; byte[] result = mac.doFinal(str.getBytes(StandardCharsets.UTF_8));&nbsp; &nbsp; &nbsp; &nbsp; // Convert the result to hex string&nbsp; &nbsp; &nbsp; &nbsp; // Like https://stackoverflow.com/questions/9655181&nbsp; &nbsp; &nbsp; &nbsp; String resultStr = ByteBufUtil.bytesToHex(result);&nbsp; &nbsp; &nbsp; &nbsp; // Compare the result with the hash from body&nbsp; &nbsp; &nbsp; &nbsp; if(hash.compareToIgnoreCase(resultStr) == 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Do other things like create a user and JWT token&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ResponseEntity.ok("ok");&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ResponseEntity.status(HttpStatus.FORBIDDEN).body(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new MessageResponse("Login info hash mismatch")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; } catch (Exception e) {&nbsp; &nbsp; &nbsp; &nbsp; logger.error(e.getMessage(), e);&nbsp; &nbsp; &nbsp; &nbsp; return ResponseEntity.status(HttpStatus.FORBIDDEN).body(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new MessageResponse("Server error while authenticating")&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Java
我要回答