Cómo cifrar un mensaje con la clave pública de una dirección de Ethereum

Estoy escribiendo un código en nodejs/browser. He creado con éxito direcciones ethereum con la biblioteca secp256k1. También pude firmar y verificar mensajes. Ahora quiero cifrar/descifrar un mensaje con la clave pública y privada de las direcciones generadas. ¿Alguien ha hecho esto antes? ¿Puedo usar CryptoJS para lograr mi objetivo?

Respuestas (2)

Gracias @Edmunx Edgar, intenté usar ECIES, pero no se pudo instalar debido a una subdependencia. Ahora usé bitcore-lib junto con bitcore-ecies . Esto funciona como se esperaba.

EDITAR: Creé un módulo npm que hace exactamente estas cosas y también tiene algunas optimizaciones de rendimiento y tutoriales : github:eth-crypto .

Aquí está mi código para cualquier persona con la misma pregunta:

// run 'npm install eth-crypto --save'

const EthCrypto = require('eth-crypto');

// create identitiy with key-pairs and address
const alice = EthCrypto.createIdentity();

const secretMessage = 'My name is Satoshi Buterin';
const encrypted = await EthCrypto.encryptWithPublicKey(
    alice.publicKey, // encrypt with alice's publicKey
    secretMessage
);

const decrypted = await EthCrypto.decryptWithPrivateKey(
    alice.privateKey,
    encrypted
);

if(decrypted === secretMessage) console.log('success');

Ejecutar a través de CodeSandbox

He estado leyendo los requisitos para los pares de claves de bitcoin y los pares de claves de Ethereum. Sus tamaños son diferentes, más específicamente una clave pública para el protocolo bitcoin es de 65 bytes (o 33 bytes comprimidos) mientras que la clave pública en ethereum es de 64 bytes. El código anterior no funciona para un par de claves de Ethereum. Sin embargo, puede usar Ethereum privKey para generar una nueva pubKey de la biblioteca anterior de esta manera. var pubKey = new bitcore.PublicKey.fromPrivateKey(privKey);Ahora puede cifrar y descifrar mensajes. ¿Alguna sugerencia sobre cómo puedo usar esta biblioteca sin tener una solución alternativa? ¡Gracias!
@Malone no, lo siento, actualmente no conozco una solución sin la solución alternativa. También mencionar que parece que bitcore-ecies tiene problemas de rendimiento.
@pubkey después de investigar esto un poco más, opté por mantener el método de cifrado anterior. Estoy usando el siguiente [ github.com/flyswatter/eth-sig-util](código) para ayudar a obtener Ethereum pubKey de forma segura (bastante útil para obtener información clave mediante la firma de Tx). Estoy construyendo un prototipo y este cifrado no sucederá muy a menudo, así que no estoy demasiado preocupado si tengo bitcore-eciesproblemas de rendimiento en este momento. Gracias de nuevo.
Hola, @Malone, ¿puedes ayudarme con el método de encriptación que usaste? En el código compartido anteriormente, ha generado la forma de clave privada y pública bitcore-lib, que usted mencionó correctamente que no funciona con la dirección de Ethereum. Entonces, ¿sería posible compartir el fragmento de código conmigo, la forma en que lo logró? el cifrado Estoy generando la clave usando kobl.one/blog/create-full-ethereum-keypair-and-address blog. y cuando estoy usando el par de claves generado a través de este blog, me está dando un error. Por favor publique una respuesta a esto si es posible
Me encanta el nombre que elegiste! Ja ja
¿Hay alguna forma de descifrar con un proveedor web3? No tengo acceso directo a la clave privada, pero puedo firmar mensajes con un proveedor web3 como Metamask.
Esto no funciona para las direcciones públicas normales de ethereum, por ejemplo: 0x9a53113da6c670ab04bc80efab364615e54cf1eb. Todas las claves públicas en los ejemplos son mucho más largas, por ejemplo, e0d262b939cd0267cfbe3f004e2863d41d1f631ce33701a8920ba73925189f5d15be92cea3c58987aa47ca70216182ba6bd89026fc15edfe2092a46f039a. ¿Alguien puede explicar cómo hacer esto con las direcciones eth cortas normales?
@PASH la dirección eth es un hash de la clave pública. Debido a cómo funciona el hashing, se pierde información. Por lo tanto, nunca es posible utilizar la dirección para el cifrado. Tienes que recuperar la clave pública que pertenece a la dirección. Puede usar el módulo eth-crypto para asegurarse de que la clave realmente pertenece a esa dirección, ejecutando la función hash nuevamente.
@pubkey Es posible obtener la clave pública de una dirección siempre que haya enviado una transacción, consulte, por ejemplo, ethereum.stackexchange.com/a/13892/56242 Ahora también es posible descifrar un mensaje usando metamask con eth_decrypt( docs .metamask.io/guide/rpc-api.html#other-rpc-methods )

Suponiendo que tenga la clave pública de la persona a la que desea enviar un mensaje (si ya ha firmado una transacción, puede recuperarla de la firma), debería ser posible cifrar y descifrar utilizando ECIES. Aparentemente, hay una biblioteca de JavaScript para esto, supongo que puede usarla en un navegador: https://bitcointalk.org/index.php?topic=627927.0

No tengo idea de si estas bibliotecas son lo suficientemente buenas como para usarlas de forma segura.

Otro enfoque es generar un par de claves separado que en realidad esté diseñado para el cifrado, luego usar la clave Ethereum para firmar la clave pública y enviarla a la otra parte.