引言
今天看了一篇数据安全相关的文章,联想到在做练习时一些密码数据都是使用 MD5 加密之后的密钥来存储的。突发奇想如果银行中用户的支付密码的数据也只用简单的 MD5 加密的话,考虑到支付密码只有 6 位,组合一共才 1E6 可能性。这时如果我直接枚举所有的可能性然后生成对应的 MD5 码并且使用哈希表来存储,这样我就可以通过对应的 MD5 码来直接查到密码原文。就算有可能多个密码会生成同一个 MD5 码,这种可能性也不是很大,最终也能找到几个候选的原文密码。
当然以上只是我的幻想,实际上银行存储密码的方式肯定比这种方式复杂得多。而且即便追求简单也可以使用另外一种方法来存储密码:连续求两次 MD5 码,这样即便是想暴力破解也没那么容易了。
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <openssl/md5.h>
#include <unordered_map>
#include <vector>
#include <sstream>
#include <iomanip>
using namespace std;
const int N = 1000000;
string gen_str(int x) {
string res = "000000";
for (int i = res.size() - 1; i >= 0 && x > 0; -- i) {
res[i] = x % 10 + '0';
x /= 10;
}
return res;
}
string gen_md5(string x) {
vector<unsigned char> res(MD5_DIGEST_LENGTH);
MD5_CTX ctx;
MD5_Init(&ctx);
MD5_Update(&ctx, x.c_str(), x.size());
MD5_Final(res.data(), &ctx);
stringstream ss;
for (unsigned char byte : res) {
ss << hex << setw(2) << setfill('0') << (int)byte;
}
return ss.str();
}
int main() {
unordered_map<string, vector<string>> hash_table;
for (int i = 0; i < N; ++ i) {
string s = gen_str(i);
string x = gen_md5(s);
// cout << s << " | " << x << endl;
hash_table[x].push_back(s);
}
string s;
do {
cout << "input md5 of password: " << endl;
cin >> s;
cout << "It's password maybe is :" << endl;
for (string s : hash_table[s]) {
cout << s << endl;
}
cout << endl;
} while (s != "over");
}
编译:g++ xxx.cpp -o xxx -lcrypto