I am trying to encrypt and decrypt messages with EthCrypto.js.
I am getting a signature on the front end via
const accounts = await window.ethereum.request({method: 'eth_requestAccounts'});
const account = accounts[0];
const signatureHash = await web3.value.eth.personal.sign('Signature verification for video file encryption', account);
The account address is 0x500694d00eFc0315Cac629b83Dfd11C8b038AfAa
Encryption works fine:
const signature = '0x27b76aa76e75d3a723883629b532b771ec860edb338b0c8421244bbd1f3d0f7078eb7bd17aad73823b0d401e917e7edcc5ca267a34623f4c7e4b3cefbfab7ac31b'
const plaintext = 'test message'
const publicKey = EthCrypto.recoverPublicKey(
signature,
EthCrypto.hash.keccak256('Signature verification for video file encryption')
);
const encrypted = await EthCrypto.encryptWithPublicKey(publicKey, plaintext);
return EthCrypto.cipher.stringify(encrypted);
I get back an object which looks right:
{
"iv": "89f37bdafdcb156603804be2bbc4acb3",
"ephemPublicKey": "04a0e2b193a5e00442f72c69ca035e9f29d9d98e719b8e86d172f14dae1912e443bb35333a776a43b63d6b87108e1f0b1bf0fcdab0e47a7669da9d80b7d7e644ba",
"ciphertext": "46d5b09c5aad80cbe9e264133afa13e0",
"mac": "c8237beb6bcee4f5afd361ce0d20364e4bfa533cb530fd1c3821c6e220b8bf7a"
}
then stringify it: const encrypted = await EthCrypto.encryptWithPublicKey(publicKey, plaintext);
The resulting string destringifies into the original object just fine: const parsed = EthCrypto.cipher.parse(ciphertext);
But when I try to decrypt with the private key const decrypted = await EthCrypto.decryptWithPrivateKey(privateKey,parsed);
I get a Bad MAC error.
Why is this? It seems like a bug. How do I fix it?
Solved here:
The issue is that web3.eth.personal.sign() appends additional characters to the string. Therefore, recovering the public key or address from the signature needs to be done thusly:
const address2 = EthCrypto.recover( signature, EthCrypto.hash.keccak256( "\x19Ethereum Signed Message:\n" + message.length + message ) );