密码学原理_Crypto++实现SHA-1近似碰撞寻找

来源:互联网 发布:网络基础技术视频教程 编辑:程序博客网 时间:2024/06/05 08:32

Requirements

请用 Crypto++实现一个程序,寻找 SHA-1 的 “近似碰撞”。也就是说,要找到两个输入a 和 b,满足 a≠b,但是 SHA1(a)和 SHA1(b)有尽可能多的对应比特相同。请说明你找到的 SHA1(a)和 SHA1(b)有多少个比特相同。请提交找到的 a 和 b 的值,以及它们的 Hash 值。

Compilation Options

g++ SHA1.cpp -o SHA1 -lcryptopp

Description

According to birthday attack, I calculate that the probability of no less than 113 bits’ partial collision with 10,000,000 attempts is 60.88% and 31.57% for 114 bits. With the help of Mathematica, I get the exact probability. Here is the source code:

In[1]:= p = N[Sum[Binomial[160, i]/(2^160), {i, 113, 160}]]Out[1]= 9.38456*10^-8In[2]:= N[1 - (1 - p)^10000000]Out[2]= 0.608768
In[3]:= p = N[Sum[Binomial[160, i]/(2^160), {i, 114, 160}]]Out[3]= 3.79404*10^-8In[4]:= N[1 - (1 - p)^10000000]Out[4]= 0.315731

Source Code

#include <iostream>#include <string.h>#include <time.h>#include <cryptopp/cryptlib.h>#include <cryptopp/sha.h>#include <cryptopp/hex.h>using namespace std;using namespace CryptoPP;const int SIZE_CHAR = 32;const int SIZE_SPACE = 10000000;const int UP_BOUND = 113;const char CCH[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";string gen_rand_str();string calculate_hash(string);string convert_hex_binary(string);int main() {    srand((unsigned)time(NULL));    int no = SIZE_SPACE;    while (no--) {        string str1 = gen_rand_str();        string str2 = gen_rand_str();        string hash1 = calculate_hash(str1);        string hash2 = calculate_hash(str2);        string binary_str1 = convert_hex_binary(hash1);        string binary_str2 = convert_hex_binary(hash2);        int counter = 0;        for (int i = 0; i < 160; i++) {            if (binary_str1[i] == binary_str2[i]) counter++;        }        if (counter > UP_BOUND) {          cout << str1 << ": " << hash1 << endl;          cout << str2 << ": " << hash2 << endl;          cout << counter << endl;        }    }    return 0;}string gen_rand_str() {    char ch[SIZE_CHAR + 1] = {0};    for (int i = 0; i < SIZE_CHAR; ++i) {        int x = rand() / (RAND_MAX / (sizeof(CCH) - 1));        ch[i] = CCH[x];    }    return ch;}string calculate_hash(string str) {      int bs_size = SIZE_CHAR * sizeof(wchar_t);      byte* bytes_string = new byte[bs_size];      int n = 0; //real bytes count      for (int i = 0; i < SIZE_CHAR; i++) {            wchar_t wcharacter = str[i];            int high_byte = wcharacter & 0xFF00;            high_byte = high_byte >> 8;            int low_byte = wcharacter & 0xFF;            if (high_byte != 0) {                bytes_string[n++] = (byte)high_byte;            }            bytes_string[n++] = (byte)low_byte;          }      SHA1 sha1;      string hash;      StringSource ss(bytes_string, n, true, new HashFilter(sha1, new HexEncoder(new StringSink(hash))));      return hash;}string convert_hex_binary(string str) {    string binary_str;    for (int i = 0; i < str.size(); i++) {      if (str[i] == '0') {          binary_str += "0000";      }      else if (str[i] == '1') {          binary_str += "0001";      }      else if (str[i] == '2') {          binary_str += "0010";      }      else if (str[i] == '3') {          binary_str += "0011";      }      else if (str[i] == '4') {          binary_str += "0100";      }      else if (str[i] == '5') {          binary_str += "0101";      }      else if (str[i] == '6') {          binary_str += "0110";      }      else if (str[i] == '7') {          binary_str += "0111";      }      else if (str[i] == '8') {          binary_str += "1000";      }      else if (str[i] == '9') {         binary_str += "1001";      }      else if (str[i] == 'A') {          binary_str += "1010";      }      else if (str[i] == 'B') {          binary_str += "1011";      }      else if (str[i] == 'C') {          binary_str += "1100";      }      else if (str[i] == 'D') {          binary_str += "1101";      }      else if (str[i] == 'E') {          binary_str += "1110";      }      else if (str[i] == 'F') {          binary_str += "1111";      }  }  return binary_str;}

Conclusion

I find a partial collision of 114 bits.

string 1

wjVaOoXXTn3BlSfmeHsjKlDIhkIV2mJe

hash1

38AB61B399F8FFB4AB159983C3FD757EED9B5CAD

string 2

7zjH48XHmH8J7xM15IZT0CJgInvjGryR

hash2

100A253FD8B06795A35DDDABE7F92466869A0E95
原创粉丝点击