I understood that web3.eth.sign(...)
will add “\x19Ethereum Signed Message” prefix to a message and hash with keccak256. Is there anyway to remove the prefix before signing? Or any library I can use to do a simple signing without prefix?
3 Answers
ethereumjs-util has the hashPersonalMessage
method which adds the prefix and signs it.
You can look at the codebase and see how this is implemented:
exports.hashPersonalMessage = function (message) {
var prefix = exports.toBuffer('\u0019Ethereum Signed Message:\n' + message.length.toString())
return exports.sha3(Buffer.concat([prefix, message]))
}
It is fairly apparent how you can modify this code snippet to not prepend the prefix :)
-
Im new to this, so I will need to modify the source of ethereumjs-util and redeploy it somehow? Currently I am executing the javascript on geth, how can I deploy the code change?– ConsyAug 17, 2017 at 12:55
-
It is Javascript. Download the JS and edit it.. Include it in a html file, or import it (using require) into a node console. Aug 17, 2017 at 13:32
No, signing without the "\x19Ethereum Signed Message" prefix is unsafe and dangerous.
For example, see https://github.com/ethers-io/ethers.js/issues/555 by ricmoo:
This is not, in general, possible and is incredibly unsafe. :s
Basically, allowing signing raw messages, without a prefix, enables an app to steal all ether, tokens and assets, which is why MetaMask does not permit you to perform this operation, and it will always force prefixing a signed message (even when the message is a hash, it will still prefix it, just with the embedded message length of 32).
Still from ethereumjs/ethereumjs-util:
exports.ecsign = function (msgHash, privateKey) {
const sig = secp256k1.sign(msgHash, privateKey)
const ret = {}
ret.r = sig.signature.slice(0, 32)
ret.s = sig.signature.slice(32, 64)
ret.v = sig.recovery + 27
return ret
}