[英]Increasing probability of finding a hash collision
I'm trying to find a hash collision of my modified hash function. 我正在尝试查找修改后的哈希函数的哈希冲突。 Assuming my modified hash only outputs the first 36 bits of SHA-1.
假设修改后的哈希仅输出SHA-1的前36位。 As we know, SHA-1 is a 160-bit hash value, hence, we only need to output 9 characters out of 40 characters for comparison.
众所周知,SHA-1是一个160位的哈希值,因此,我们只需要输出40个字符中的9个字符进行比较即可。
How i begin my program is by hashing a string (I have a SHA-1 algorithm running and i will name it as sha1. I have also ensured that the output of the SHA-1 algorithm is correct.) 我如何通过哈希字符串开始程序(我正在运行SHA-1算法,并将其命名为sha1。我还确保SHA-1算法的输出正确。)
Firstly, i would hardcode 2 string and extract out 9 characters out of 40 characters since i require only the first 36 bits of SHA-1. 首先,我将硬编码2个字符串并从40个字符中提取9个字符,因为我只需要SHA-1的前36位。 The function below basically return a true if a collision is found and false if a collision is not found
如果发现冲突,下面的函数基本上返回true;如果未发现冲突,则返回false
public static boolean findCollision(int x1, int x2) {
String message1 = "I tried " + x1 + " iteration to find a collision";
String message2 = "I tried " + x2 + " iteration to find a collision";
//hashing my string and extracting 9 characters
String message_hash1 = sha1(message1);
String message_hash2 = sha1(message2);
String modified_hash1 = message_hash1.substring(0, 9);
String modified_hash2 = message_hash2.substring(0, 9);
if (modified_hash1.equals(modified_hash2))
return true;
else
return false;
}
Lastly, i will have a main function that will random Integers up to MAX_VALUE in a infinite loop and will break out if and only if a hash is found. 最后,我将拥有一个主函数,该函数将在无限循环中将Integer最多随机化到MAX_VALUE,并且仅当找到哈希后才会中断。
public static void main(String[] args) {
Random random = new Random();
int x1 = 0;
int x2 = 0;
int counter = 0;
while (true) {
while(true){
x1 = random.nextInt(Integer.MAX_VALUE);
x2 = random.nextInt(Integer.MAX_VALUE);
if (x1 != x2)
break;
}
if (findCollision(x1, x2) == true) {
break;
}
counter++;
}
System.out.println("\nNumber of trials: " + counter);
}
If i tried taking only the first 24 bits of SHA-1, i could easily find a collision. 如果我仅尝试使用SHA-1的前24位,那么我很容易发现冲突。 However, i'm unable to find a collision for 36 bits instead despite running it for hours.
但是,尽管运行了几个小时,但我找不到36位的碰撞。 Hence, I'm wondering what is other alternative way for me to find a collision with just 36 bits of SHA-1.
因此,我想知道还有什么其他方法可以找到仅36位SHA-1的碰撞。
https://stackoverflow.com/users/1081110/dawood-ibn-kareem is correct that the optimal method is to remember the previous hashes and check against them, as long as this is practical ie fits in memory, and the roughly 2^18 values needed for 36 bit collision do fit in memory, though only a little more (about 50 bits) would not. https://stackoverflow.com/users/1081110/dawood-ibn-kareem是正确的,最佳方法是记住以前的哈希并检查它们,只要可行(即适合内存),大约2 ^ 36位冲突所需的18个值确实适合内存,尽管只有一点点(大约50位)不适合。
This code finds 8 collisions below 2^20 (the first one slightly under 2^18 as expected) in about a second: 这段代码会在大约一秒钟的时间内找到8个低于2 ^ 20的碰撞(第一个碰撞比预期的稍微低于2 ^ 18):
static void SO56263762TruncCollision (String[] args) throws Exception {
int[][] known = new int[1<<24][];
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
for( int i = 0; i < (1<<20); i++ ){
byte[] raw = sha1.digest(("I tried "+i+" iterations to find a collision").getBytes());
int key = 0; for( int j = 0; j < 3; j++ ) key = key<<8 | (raw[j]&0xFF);
char[] val = new char[9]; for( int j = 0; j < 9; j++ ) val[j] = Character.forDigit(j%2==0? (raw[j/2]>>4)&0xF: raw[j/2]&0xF, 16);
int[] test = known[key];
if( test == null ){ (known[key] = new int[1])[0] = i; }
else{
for( int k = 0; k < test.length; k++ ){
byte[] raw2 = sha1.digest(("I tried "+test[k]+" iterations to find a collision").getBytes());
char[] val2 = new char[9]; for( int j = 0; j < 9; j++ ) val2[j] = Character.forDigit(j%2==0? (raw2[j/2]>>4)&0xF: raw2[j/2]&0xF, 16);
if( Arrays.equals(val, val2)) System.out.println ("found "+i+" and "+test[k]);
}
(known[key] = Arrays.copyOf(test, test.length+1))[test.length] = i;
}
}
System.out.println ("Memory="+(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()) );
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.