Which function should be used to sign message locally? Which function is the most secure?
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.