检查散列值是否相同

Checking if hashed values are the same

我正在使用 SHA-256 对用户令牌进行哈希处理,然后将该哈希值保存到 db 中,最后当新令牌到达时,我将拉出之前保存的令牌并使用 equals 方法进行检查,这样可以吗?或者 byte[] 需要以某种方式进行不同的检查?

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");
    }
}

你的代码没问题。

Arrays.equals() 进行 element-for-element 比较。引用 javadoc:

Returns true if the two specified arrays of bytes are equal to one another. Two arrays are considered equal if both arrays contain the same number of elements, and all corresponding pairs of elements in the two arrays are equal. In other words, two arrays are equal if they contain the same elements in the same order. Also, two array references are considered equal if both are null.

您的代码有效,但还可以改进。如果我理解正确的话,攻击者可以窃取用户的开放会话,前提是他能够猜出哈希用户令牌。

您当前的比较 returns 错误,只要第一个字节不相等。因此,较早位置的不平等 returns 比较晚位置的差异更快。攻击者可以对响应时间使用定时攻击来对当前令牌进行逆向工程。因此,您应该使用慢等式方法,该方法始终比较数组中的所有字节并始终花费相同的时间来比较值。

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 还解释了定时攻击问题。