问题描述
我正在使用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()
进行元素对元素的比较。引用javadoc:
,如果两个指定的字节数组彼此相等,则返回true。如果两个数组包含相同数量的元素,并且两个数组中所有对应的元素对均相等,则认为两个数组相等。换句话说,如果两个数组包含相同顺序的相同元素,则它们相等。另外,如果两个数组引用都为空,则认为它们相等。
您的代码可以工作,但是可以改进。如果我正确理解,攻击者可以猜测散列的用户令牌,从而可以窃取用户的公开会话。
当第一个字节不相等时,您当前的比较将返回false。因此,较早位置的不平等回报要比较晚位置的差更快。攻击者可以对响应时间使用定时攻击来对当前令牌进行反向工程。因此,您应该使用慢速等于方法,该方法始终比较数组中的所有字节,并始终花费相同的时间比较值。
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 还解释了定时攻击问题。