I found a post describing how to recover an Ethereum wallet keystore by guessing a single password, however, it uses node synchronous code, and I'm trying to convert it into asynchronous code so that I can use multithreading using worker_threads.
run.js (snippet)
for (let x = 0; x <= maxX*passesPerThread; x++) {
passes[x +1] = c.iterate(passes[x], chars)
}
for (let x = 0; x < maxX; x++) {
dcWorker[x] = new Worker('./worker.js', { workerData: { FILE: FILE, PASSWORD: passes[x*passesPerThread], workerNum: x, passesPerThread: passesPerThread, CHARS: chars}, })
dcWorker[x].on('message', (data) => {
if (data.status === 'done') {
console.log(" w" + x + "d")
}
})
}
crack.js (snippet)
function crack(PASSWORD, FILE) {
const data = fs.readFile(FILE, {encoding: "utf8"}, (err, data) => {
if (err) throw err
const content = data
attempt(data, PASSWORD, FILE)
})
}
function attempt(data, PASSWORD, FILE) {
const keythereum = require("keythereum")
const keyObject = JSON.parse(data)
keythereum.recover(PASSWORD, keyObject, privateKey => {
if (!privateKey.toString() === "message authentication code mismatch") {
console.log("\npossible password: " + PASSWORD + "\naddress: " + `0x${keyObject.address}` + "\npriv key: " + `0x${privateKey}`)
savePass(PASSWORD, FILE)
//process.exit()
}
})
}
worker.js (snippet)
passes = new Array()
passes[0] = pass
maxX = workerData.passesPerThread
const cProm =
new Promise((resolve, reject) => {
for (let x = 1; x < maxX; x++) {
passes[x] = c.iterate(passes[x -1], chars)
}
resolve('done')
})
.then(value => {
for (let x = 1; x < maxX; x++) {
process.stdout.write(" w" + workerData.workerNum + "a" + passes[x] + "T" + Date.now() + ", ")
c.crack(passes[x], FILE)
}
parentPort.postMessage({ status: value })
})
.catch(err => {
parentPort.postMessage({ status: err })
})
I don't understand why the stack is processing all output before actually attempting each crack attempt.
The following is output, then a long pause while it attempts to crack ONE password for each thread, instead of many passwords per thread like the output seems to indicate:
w1aeasyaspsi, w1d
w1aeasyaspsi,
w1aeasyaspyeT1641634988273, w1aeasyaspyaT1641634988274, w1aeasyaspysT1641634988274, w1aeasyaspyyT1641634988274, w1aeasyaspypT1641634988274, w1aeasyaspyiT1641634988274, w1aeasyasppeT1641634988274, w1aeasyasppaT1641634988274, w1aeasyasppsT1641634988274, w0aeasyaspaa, w3aeasyasiea, w0d
w3d
w0aeasyaspaa,
w0aeasyaspasT1641634988279, w0aeasyaspayT1641634988280, w0aeasyaspapT1641634988280, w0aeasyaspaiT1641634988280, w0aeasyaspseT1641634988280, w0aeasyaspsaT1641634988280, w0aeasyaspssT1641634988280, w0aeasyaspsyT1641634988280, w0aeasyaspspT1641634988280, w3aeasyasiea,
w3aeasyasiesT1641634988279, w3aeasyasieyT1641634988280, w3aeasyasiepT1641634988280, w3aeasyasieiT1641634988280, w3aeasyasiaeT1641634988280, w3aeasyasiaaT1641634988280, w3aeasyasiasT1641634988280, w3aeasyasiayT1641634988280, w3aeasyasiapT1641634988280, w2aeasyasppy, w2d
w2aeasyasppy,
w2aeasyaspppT1641634988296, w2aeasyasppiT1641634988297, w2aeasyaspieT1641634988297, w2aeasyaspiaT1641634988297, w2aeasyaspisT1641634988297, w2aeasyaspiyT1641634988297, w2aeasyaspipT1641634988297, w2aeasyaspiiT1641634988298, w2aeasyasieeT1641634988298,
after this is output almost instantaneously, it pauses while it attempts to crack 4 passwords, then the process drops out (without error).
I was expecting the output to pause after each comma ,
but it outputs everything before attempting anything.
The idea is to, for example, crack 10 passwords per thread, where there are 4 threads, then when the worker is terminated, a new worker in its place is started with the next 10 passwords, however, I'm just trying to run each worker_thread once to start until I can debug the rest of it.
So, my questions are:
- Why isn't it attempting all crack attempts like the output seems to indicate?
- How do I make the output align with what is actually being attempted when it's being attempted?