在我学校的任务中,我的任务是暴力破解 SHA1 哈希以找到密钥。
我们得到了标志(在 SHA1 中)、密码(在 SHA1 中),他们告诉我们密钥是 [AAAAAA-ZZZZZZ]。该标志的格式为 SHA1(PASSWORD_KEY)。
我能够通过彩虹表方法获取密码,现在我需要从 AAAAAA-ZZZZZZ 暴力破解密钥。下面是我想出的代码
function guess(flag, password) {
for (let char1 = 65; char1 <= 90; char1++) {
for (let char2 = 65; char2 <= 90; char2++) {
for (let char3 = 65; char3 <= 90; char3++) {
for (let char4 = 65; char4 <= 90; char4++) {
for (let char5 = 65; char5 <= 90; char5++) {
for (let char6 = 65; char6 <= 90; char6++) {
const key_guess = String.fromCharCode(char1, char2, char3, char4, char5, char6);
const guess = `${password}_${key_guess}`;
const shasum = crypto.createHash('sha1');
shasum.update(guess);
const hashed_guess = shasum.digest('hex');
if (hashed_guess === flag) {
return key_guess;
}
}
}
}
}
}
}
}
这行得通,但我的电脑花了大约 23 秒来破解密钥。由于我是在 nodejs 中编写此代码的,因此我考虑过使用 promise 包装将蛮力卸载到多个内核(我使用的是 AMD 5600x,因此有 6 个物理内核)所以我想出了这段代码
async function guessKey(flag, password) {
return new Promise(async (resolve) => {
async function guessPromise(startCharAscii, endCharAscii) {
return new Promise((resolve) => {
for (let char1 = startCharAscii; char1 <= endCharAscii; char1++) {
for (let char2 = 65; char2 <= 90; char2++) {
for (let char3 = 65; char3 <= 90; char3++) {
for (let char4 = 65; char4 <= 90; char4++) {
for (let char5 = 65; char5 <= 90; char5++) {
for (let char6 = 65; char6 <= 90; char6++) {
const key_guess = String.fromCharCode(char1, char2, char3, char4, char5, char6);
const guess = `${password}_${key_guess}`;
const shasum = crypto.createHash('sha1');
shasum.update(guess);
const hashed_guess = shasum.digest('hex');
if (hashed_guess === flag) {
resolve(key_guess);
}
}
}
}
}
}
}
});
}
const NUMBER_OF_CORES = 6;
const promiseList = [];
let startCharAscii = 65;
// 6 cores
for (let i = 0; i < NUMBER_OF_CORES; i++) {
// split into 5, 5, 4, 4, 4, 4
// btwn cores 0, 1, 2, 3, 4, 5
// core 0: [65, 69]
// core 1: [70, 74]
// core 2: [75, 78]
// core 3: [79, 82]
// core 4: [83, 86]
// core 5: [87, 90]
if (i === 0 || i === 1) {
// 5 letters
promiseList.push(guessPromise(startCharAscii, startCharAscii + 4));
startCharAscii += 5;
} else {
promiseList.push(guessPromise(startCharAscii, startCharAscii + 3));
startCharAscii += 4;
}
}
await Promise.all(promiseList);
resolve(promiseList.find((x) => x !== undefined));
});
}
(async () => {
console.time(`time`);
console.log(await guessKey(flag, password));
console.timeEnd(`time`);
})();
但是将待处理的承诺推入列表似乎需要很长时间,这不应该发生,因为它还没有实现。我是否遗漏了什么或者nodeJS中的异步操作没有利用多核?