检查哈希值是否相同

92dk7w1h  于 2021-07-04  发布在  Java
关注(0)|答案(2)|浏览(264)

我使用sha-256对用户令牌进行散列,然后将散列值保存到db中,最后当新令牌到达时,我提取之前保存的令牌并使用equals方法进行检查,可以吗?或者字节[]需要进行不同的检查?
if (!Arrays.equals(hashedToken, tokenEntity.get().getToken())) ```
private byte[] hashToken(String token) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
return digest.digest(token.getBytes(StandardCharsets.UTF_8));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("No such algorithm exist");
}
}

8dtrkrch

8dtrkrch1#

你的密码很好。 Arrays.equals() 进行元素对元素的比较。引用javadoc:
如果指定的两个字节数组彼此相等,则返回true。如果两个数组包含相同数量的元素,并且两个数组中所有对应的元素对都相等,则认为两个数组相等。换句话说,如果两个数组包含相同顺序的相同元素,那么它们是相等的。另外,如果两个数组引用都为null,则认为它们相等。

ttcibm8c

ttcibm8c2#

你的代码可以工作,但可以改进。如果我理解正确,攻击者可以窃取用户的打开会话,如果他能够猜出散列的用户令牌。
当第一个字节不相等时,当前比较返回false。因此,在一个较早的位置上的不一致比在一个较晚的位置上的差异更快地返回。攻击者可以利用响应时间上的计时攻击对当前令牌进行反向工程。因此,您应该使用慢的equals方法,该方法总是比较数组中的所有字节,并且总是花费相同的时间来比较值。

private static boolean slowEquals(byte[] a, byte[] b) {
    int diff = a.length ^ b.length;
    for(int i = 0; i < a.length && i < b.length; i++) {
        diff |= a[i] ^ b[i];
    }
    return diff == 0;
}

这是一个很好的安全准备:https://crackstation.net/hashing-security.htm 还解释了定时攻击问题。

相关问题