Firmar sin el prefijo “\x19Ethereum Signed Message”

Entendí que web3.eth.sign(...)agregará el prefijo "\x19Ethereum Signed Message" a un mensaje y hash con keccak256. ¿Hay alguna forma de eliminar el prefijo antes de firmar? ¿O alguna biblioteca que pueda usar para hacer una firma simple sin prefijo?

Respuestas (3)

ethereumjs-util tiene el hashPersonalMessagemétodo que agrega el prefijo y lo firma.

Puede mirar el código base y ver cómo se implementa esto:

exports.hashPersonalMessage = function (message) {
  var prefix = exports.toBuffer('\u0019Ethereum Signed Message:\n' + message.length.toString())
  return exports.sha3(Buffer.concat([prefix, message]))
}

Es bastante evidente cómo puede modificar este fragmento de código para no anteponer el prefijo :)

Soy nuevo en esto, así que tendré que modificar la fuente de ethereumjs-util y volver a implementarla de alguna manera. Actualmente estoy ejecutando javascript en geth, ¿cómo puedo implementar el cambio de código?
Es Javascript. Descargue el JS y edítelo. Inclúyalo en un archivo html o impórtelo (usando require) en una consola de nodo.

No, firmar sin el prefijo "\x19Ethereum Signed Message" es inseguro y peligroso.

Por ejemplo, consulte https://github.com/ethers-io/ethers.js/issues/555 de ricmoo:

Esto no es, en general, posible y es increíblemente inseguro. :s

Básicamente, permitir la firma de mensajes sin formato, sin un prefijo, permite que una aplicación robe todos los éteres, tokens y activos, por lo que MetaMask no le permite realizar esta operación, y siempre forzará el prefijo de un mensaje firmado (incluso cuando el mensaje es un hash, aún lo prefijará, solo con la longitud del mensaje incrustado de 32).

Fotograma de 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
}