代码之家  ›  专栏  ›  技术社区  ›  PatPanda

Java-TOTP算法,从HMAC SHA1到HMAC SHA256

  •  0
  • PatPanda  · 技术社区  · 4 年前

    关于TOTP生成算法的小问题。

    我正在构建一个TOTP生成算法。为了做到这一点,我使用HMAC SHA1。 结果是正确的,我多次使用HMAC SHA1生成的TOTP向服务器验证自己,我确认TOTP是正确的,非常高兴。

    现在,知道HMAC SHA1不太安全,我想从HMAC SHA1迁移到HMAC SHA256。

    我以为我只是简单地改变了HMAC算法。不幸的是,服务器不接受使用HMAC SHA256生成的所有TOTP。

    只是想强调一下,这个问题是关于如何让它与HMAC SHA256一起工作。

    这个问题不是关于:

    • HMAC SHA1有多安全
    • 如果从HMAC SHA1迁移到HMAC256是一个不错的选择
    • 如何更改服务器以接受HMAC256生成的TOTP。

    这个技术问题实际上是关于使用HAMC SHA256生成TOTP的技术算法。

    我用来生成HMAC SHA1 TOTP的代码是:

    String getTOTP() {
            try {
                long value = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() / TimeUnit.SECONDS.toMillis(30);
                final byte[] key = new Base32().decode("the_password".toUpperCase(Locale.US));
                final var data = new byte[8];
                for (int i = 8; i-- > 0; value >>>= 8) {
                    data[i] = (byte) value;
                }
                final var signKey = new SecretKeySpec(key, "HmacSHA1"); // would like to change here to "HmacSHA256"
                final var mac = Mac.getInstance("HmacSHA1"); // would like to change here to "HmacSHA256"
                mac.init(signKey);
                final String hashString = new String(new Hex().encode(mac.doFinal(data)));
                final var offset = Integer.parseInt(hashString.substring(hashString.length() - 1), 16);
                final var truncatedHash = hashString.substring(offset * 2, offset * 2 + 8);
                final var finalHash = String.valueOf(Integer.parseUnsignedInt(truncatedHash, 16) & 0x7FFFFFFF);
                final var finalHashCut = finalHash.substring(finalHash.length() - 6);
                System.out.println("THE TOTP generated with HmacSHA1 is  " + finalHashCut);
                System.out.println("THE TOTP generated with HmacSHA256 will not work though :'( ");
                return finalHashCut;
            } catch (NoSuchAlgorithmException | InvalidKeyException e) {
                LOGGER.warn("", e);
                return "";
            }
        }
    

    问题:为了让TOTP使用HMAC SHA256并且仍然有效,我应该调整算法的哪些元素?

    非常感谢。

    0 回复  |  直到 4 年前
        1
  •  0
  •   PatPanda    4 年前

    由于Robert的评论,更改哈希将更改输出。

    除非目标服务器接受另一个哈希算法,否则更改客户端上的哈希将产生不同的TOTP,并且服务器不会接受。