Which function should be used to sign message locally? Which function is the most secure?
What is the difference between web3.eth.sign, web3.eth.accounts.sign, web3.eth.personal.sign functions?
Which one you should use depends on whether you're running a node (like
parity), and whether that node has an unlocked account.
- No node?
- Node with unlocked account?
- Node with locked account?
eth.sign(dataToSign, address [, callback]) is a convenience function that accepts an address that your node controls, and returns a Promise for a string that is the signature. It will only work on accounts that are already unlocked.
Signs data using a specific account. This account needs to be unlocked.
A risk factor is leaving your account unlocked. That means that any process capable of interacting with your node has arbitrary access to act on your behalf.
eth.personal.sign(dataToSign, address, password [, callback]) is nearly the same, but allows you to include a password for accounts that are locked.
Signs data using a specific account.
A risk factor is passing your account password around in plaintext. Anything with access to that variable has your password.
eth.accounts.sign(data, privateKey) is a lower-level tool that allows you to pass in the private-key directly. It is synchronous, and returns more details than just the signature.
Signs arbitrary data. This data is before UTF-8 HEX decoded and enveloped as follows:
"\x19Ethereum Signed Message:\n" + message.length + message.
A risk factor is passing your private key around in plaintext. Anything with access to that variable can do arbitrary things with your account.
You're right to be paranoid, but the problems are less likely to come from the web3.js library itself, and more likely to come from how you store the variables, and ports you leave open for access. Note that web3.js v1 is still in beta, and I'm not sure when they last had a security audit.
Be very careful, and get your code audited by well-respected security professionals.
eth.accounts.signcompatible? Can you recover the signers address regardless of which of these two the message has been signed with? Dec 3, 2019 at 13:50
1It is meant to be, yes, but not every node implements
eth.personal.signthe same, unfortunately. I can't recommend this approach anymore, and we started calling this signing approach
defunctin web3.py. For simple things, I would recommend: EIP 191 with the
0x01version byte, or for more complex signatures, EIP 712 . Both are available in
eth-account: eth-account.readthedocs.io/en/stable/… and eth-account.readthedocs.io/en/stable/… respectively.– carverDec 3, 2019 at 19:58