Metamask: Got different Public keys from same Private key. `eth-crypto`’s `recoverPublicKey()` and MetaMask’s `eth_getEncryptionPublicKey`

Understanding the Difference Between MetaMask and Ethereum Public Keys

As Ethereum developers, we are no strangers to the complexities of interacting with the Ethereum blockchain. Recently, several users have been puzzled by the discrepancy between the public keys displayed in their MetaMask wallet and those retrieved using the eth_getEncryptionPublicKey RPC call.

The Problem: Different Public Keys from the Same Private Key

Let’s get into the details of what’s going on. When we use eth_getEncryptionPublicKey, it requests the public encryption key for a specific Ethereum account address. However, this public key is calculated based on the private key stored in MetaMask. Here’s why:

  • Private Key: The private key used to create an Ethereum wallet is unique to each individual.
  • Public Key Calculation:

    When you retrieve the public key using eth_getEncryptionPublicKey, it is not directly linked to your key. private. Instead, it uses a different calculation method, which generates a new set of keys (public and private) based on the shared secret between the MetaMask wallet and the Ethereum blockchain.

  • Shared Secret: This shared secret is used to obtain the public key from the private key.

Solution: recoverPublicKey() vs. eth_getEncryptionPublicKey

To resolve this issue, you can use either of the two methods:

  • recoverPublicKey():
  • You can call recoverPublicKey() on the MetaMask wallet to retrieve the public key associated with a specific Ethereum address.
  • This method provides the private key used by MetaMask and allows you to obtain the public key from it.
  • eth_getEncryptionPublicKey (RPC):

  • You can use eth_getEncryptionPublicKey as before to retrieve the public encryption key for your Ethereum account address.
  • However, note that this will return a different set of keys than if you used recoverPublicKey().

Code example: Recovering the public key with recoverPublicKey() from MetaMask

const web3 = require('web3');

const metaMask = new Web3(new Web3.providers.HttpProvider('

metaMask.getAccounts().then(accounts => {

const publicKey = accounts[0].getPublicKey();

// Recover the private key using MetaMask's recoverPublicKey method

return metaMask.recoverPublicKey(publicKey);

});

Conclusion:

The discrepancy between the public keys displayed on the MetaMask wallet and those retrieved using the eth_getEncryptionPublicKey RPC calls can be resolved using either recoverPublicKey() or eth_getEncryptionPublicKey. By understanding how Ethereum addresses, private keys, and shared secrets work together, you will be better equipped to navigate these complex interactions.

If you have any questions or need further clarification on this topic, feel free to ask!

Tags: No tags

Comments are closed.