Encontré una publicación que describe cómo recuperar un almacén de claves de billetera Ethereum adivinando una sola contraseña, sin embargo, usa código sincrónico de nodo, y estoy tratando de convertirlo en código asincrónico para poder usar subprocesos múltiples usando worker_threads.
run.js (fragmento)
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 (fragmento)
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() } }) }trabajador.js (fragmento)
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 }) })No entiendo por qué la pila procesa todos los resultados antes de intentar cada intento de crack.
Lo siguiente es la salida, luego una pausa larga mientras intenta descifrar UNA contraseña para cada subproceso, en lugar de muchas contraseñas por subproceso como parece indicar la salida:
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,después de que esto se emita casi instantáneamente, se detiene mientras intenta descifrar 4 contraseñas, luego el proceso se cierra (sin error).
Esperaba que la salida se detuviera después de cada coma , pero genera todo antes de intentar algo.
La idea es, por ejemplo, descifrar 10 contraseñas por subproceso, donde hay 4 subprocesos, luego, cuando el trabajador finaliza, se inicia un nuevo trabajador en su lugar con las siguientes 10 contraseñas, sin embargo, solo estoy tratando de ejecutar cada worker_thread una vez para comenzar hasta que pueda depurar el resto.
Entonces, mis preguntas son:
dejé de intentar entender las promesas (pero entiendo algunas de ellas), así que volví al código síncrono mientras sigo implementando verdaderos subprocesos múltiples a través cluster de nodejs y ahora funciona mucho, mucho más rápido que un solo subproceso
run.js
//(synchronous functions not displayed) //... workers = new Array() if (cluster.isMaster) { pass = "" if(PROGRESS === "CONTINUE") { if (checkFileExists(FILE + ".progress.txt")) { console.log("progress file found: continuing") try { const data = fs.readFileSync(FILE + ".progress.txt", 'utf8') pass = data } catch (err) { console.error(err) } if (!pass.length > 0) pass = chars.substring(0,1) } else { console.log("progress file not found: starting at beginning; this is ok if first time running") pass = chars.substring(0,1) } } else pass = chars.substring(0,1) let r = 0 let someLeft = true let passes = new Array() passes[0] = pass for (let y = 1; y < cpuCount; y++) passes[y] = iterate(passes[y -1]) let passTried = new Array() for (let y = 0; y < cpuCount; y++) passTried[y] = false for (let x = 0; x < cpuCount; x++) { workers[x] = cluster.fork() passTried[x] = true workers[x].send({ message: passes[x] }) workers[x].on('message', function(msg) { if (msg.stat) { for (sworker in workers) { workers[sworker].process.kill() } process.exit() } if (msg.att) { process.stdout.write("\rattempted: " + msg.att) r++ if (r % 100 == 0) { fs.writeFileSync(FILE + '.progress.txt', msg.att, function (err) { if (err) throw err }) r = 0 } for (let i = 0; i < cpuCount; i++) { if (!passTried[i]) { passTried[i] = true workers[x].send({ message: passes[i] }) break } } someLeft = false for (let i = 0; i < cpuCount; i++) { if (!passTried[i]) { someLeft = true break } } if (!someLeft) { passes = getNewBlock(passes) for (let y = 0; y < cpuCount; y++) passTried[y] = false someLeft = true } } }) } } else { process.on('message', function(pass) { crack(pass.message) process.send({ att: pass.message }) }) }tenga en cuenta que este es un trabajo de pirateo un poco feo y no debe implementarse en un servidor y definitivamente no debe implementarse en producción porque usa código de bloqueo, pero para mi propósito específico hace el trabajo
gracias a todos los que intentaron mostrarme la forma de usar el código asíncrono en los comentarios anteriores