问题描述
我正在构建一个 TOTP 生成算法。为此,我使用了 HMAC SHA1。 结果是正确的,我多次使用这个 HMAC SHA1 生成的 TOTP 来向服务器验证我自己,我确认了 TOTP 是正确的,非常高兴。
现在,知道 HMAC SHA1 不太安全,我想从 HMAC SHA1 迁移到 HMAC SHA256。
我以为我只是改变HMAC算法那么简单。不幸的是,所有使用 HMAC SHA256 生成的 TOTP 都没有被服务器接受。
强调一下,这个问题是关于如何使其与 HMAC SHA256 配合使用。
这个问题不是关于:
这个技术问题实际上是关于使用 HAMC SHA256 生成 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,并且不会被服务器接受。