MessageDigest.isEqual函数在Java中的使用
我有两个问题我不明白。请帮我看看。谢谢MessageDigest.isEqual函数在Java中的使用,java,timing-attack,Java,Timing Attack,我有两个问题我不明白。请帮我看看。谢谢 MessageDigest.isEqual函数在Java中有什么用途 解释为什么在JavaSE6Update17之前的一些版本中,它容易受到定时攻击 查看Java SE 6 Update 10实现,我们看到: public static boolean isEqual(byte digesta[], byte digestb[]) { if (digesta.length != digestb.length) return f
查看Java SE 6 Update 10实现,我们看到:
public static boolean isEqual(byte digesta[], byte digestb[]) {
if (digesta.length != digestb.length)
return false;
for (int i = 0; i < digesta.length; i++) {
if (digesta[i] != digestb[i]) {
return false;
}
}
return true;
}
publicstaticbooleaniesequal(byte-digesta[],byte-digestb[]){
if(digesta.length!=digestb.length)
返回false;
for(int i=0;i
修复后,我们看到:
public static boolean isEqual(byte[] digesta, byte[] digestb) {
if (digesta.length != digestb.length) {
return false;
}
int result = 0;
// time-constant comparison
for (int i = 0; i < digesta.length; i++) {
result |= digesta[i] ^ digestb[i];
}
return result == 0;
}
publicstaticbooleaniesequal(字节[]digesta,字节[]digestb){
if(digesta.length!=digestb.length){
返回false;
}
int结果=0;
//时间常数比较
for(int i=0;i
旧的实现似乎更有效,因为它在找到第一个不相等的字节时返回false
,但我假设它已被替换,因为它可能允许调用方根据方法的运行时间测试两个输入字节数组之间的相似性
新实现总是具有相同的运行时间(对于相同长度的数组),因为它迭代整个数组(即使数组的第一个字节不同)
我搜索了调用此方法的位置。一个例子是
com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac
类中的engineVerify(byte[]signature)
,它通过将传递给它的签名字节数组与某个内部字节数组进行比较来测试它是否有效。在修复之前,通过测量该方法的运行时间,您可以尝试生成通过比较的字节数组(该方法运行的时间越长,意味着两个数组的前缀越大)。请参阅下面的网页链接:
我可以选择要进行身份验证的消息(例如,具有特定用户ID的会话cookie),然后计算256个可能的值:
我仔细检查每一个值,直到找到一个-a100000000000000000000000000000000000000000,它比其他值长一毫秒。我现在知道该消息的HMAC的第一个字节应该是A1。对剩下的19个字节重复这个过程,突然我以您的身份登录
0000000000000000000000000000000000000000
0100000000000000000000000000000000000000
0200000000000000000000000000000000000000
... snip 250 ...
FD00000000000000000000000000000000000000
FE00000000000000000000000000000000000000
FF00000000000000000000000000000000000000