Java - TOTP算法,从HMAC SHA1到HMAC SHA256
Java - TOTP algorithm, from HMAC SHA1 to HMAC SHA256
请问一个关于 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 并且仍然有效,我应该调整算法的哪些元素?
谢谢。
感谢 Robert 的评论,更改散列将更改输出。
除非目标服务器接受其他哈希算法,否则在客户端更改哈希会产生不同的 TOTP,并且不会被服务器接受。
请问一个关于 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 并且仍然有效,我应该调整算法的哪些元素?
谢谢。
感谢 Robert 的评论,更改散列将更改输出。
除非目标服务器接受其他哈希算法,否则在客户端更改哈希会产生不同的 TOTP,并且不会被服务器接受。