0

在我学校的任务中,我的任务是暴力破解 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中的异步操作没有利用多核?

4

0 回答 0