Abh*_*hek 7 java bitwise-operators bitwise-xor
我在产品代码中看到了以下代码段.它使用按位XOR进行字符串比较.这比String.equals(Object o)方法好吗?作者试图在这里实现什么?
private static boolean compareSecure(String a, String b)
{
if ((a == null) || (b == null)) {
return (a == null) && (b == null);
}
int len = a.length();
if (len != b.length()) {
return false;
}
if (len == 0) {
return true;
}
int bits = 0;
for (int i = 0; i < len; i++) {
bits |= a.charAt(i) ^ b.charAt(i);
}
return bits == 0;
}
Run Code Online (Sandbox Code Playgroud)
对于上下文,等同的字符串是身份验证令牌.
这是字符串比较函数的常见实现,不受计时攻击的影响。
简而言之,这个想法是在每次比较字符串时比较所有字符,即使您发现它们中的任何一个不相等。在“标准”实现中,您只需打破第一个差异并返回 false。
这并不安全,因为它会泄露有关比较字符串的信息。具体来说,如果左侧字符串是您想要保留的秘密(例如密码),而右侧字符串是用户提供的内容,则不安全的方法允许黑客通过反复尝试相对轻松地发现您的密码输出不同的字符串并测量响应时间。两个字符串中相同的字符越多,“不安全”函数就越需要比较它们。
例如,使用标准方法比较“1234567890”和“0987654321”将导致仅对第一个字符进行一次比较并返回 false,因为 1!=0。另一方面,将“1234567890”与“1098765432”进行比较,将导致执行 2 个比较操作,因为第一个比较操作相等,您必须比较第二个以发现它们不同。这会花费更多时间,而且是可以衡量的,即使我们谈论的是远程调用。
如果您使用 N 个不同的字符串进行 N 次攻击,每个字符串以不同的字符开头,您应该看到其中一个结果比其余的多几分之一毫秒。这意味着第一个字符是相同的,因此该函数必须花费更多时间来比较第二个字符。冲洗并重复字符串中的每个位置,您可以比蛮力更快地破解秘密数量级。
防止此类攻击是此类实施的重点。
编辑:正如Mark Rotteveel在评论中指出的那样,这个实现仍然容易受到旨在揭示字符串长度的定时攻击的影响。在许多情况下这仍然不是问题(要么你不关心攻击者知道长度,要么你处理标准的数据并且任何人都可以知道长度,例如某种已知长度的哈希)
| 归档时间: |
|
| 查看次数: |
1322 次 |
| 最近记录: |