我使用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");
}
}
您的代码是有效的,但它可以改进。如果我理解正确,攻击者可以窃取用户的打开会话,如果他能够猜测哈希用户令牌的话。
一旦第一个字节不相等,当前比较就会返回false。因此,前一个位置上的不相等比后一个位置的差返回得更快。攻击者可以对响应时间进行定时攻击,对当前令牌进行逆向工程。因此,您应该使用slow-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;
}
这里有一个关于hasing和安全的好准备:https://crackstation.net/hashing-security.htm也解释了定时攻击问题。
您的代码很好。
CCD_ 2进行元素对元素比较。引用javadoc:
如果两个指定的字节数组彼此相等,则返回true。如果两个数组都包含相同数量的元素,并且两个数组中所有对应的元素对都相等,则两个数组被视为相等。换句话说,如果两个数组以相同的顺序包含相同的元素,那么它们是相等的。此外,如果两个数组引用都为null,则认为它们相等。