18/07/2023
En el ecosistema de Ethereum y las aplicaciones descentralizadas (DApps), interactuar con la blockchain va más allá de simplemente enviar transacciones. A menudo, se nos solicita "firmar un mensaje" para demostrar la propiedad de una wallet, iniciar sesión en una plataforma sin necesidad de contraseña o autorizar ciertas acciones fuera de la cadena. Sin embargo, no todos los métodos de firma son iguales, y usar el incorrecto puede abrir la puerta a vulnerabilidades críticas. Aquí es donde entra en juego personal_sign, un método diseñado específicamente para firmar mensajes de forma segura, protegiendo a los usuarios de posibles ataques de suplantación de identidad.

Comprender la diferencia entre los distintos métodos de firma es fundamental para cualquier usuario de criptomonedas. Una simple firma puede parecer inofensiva, pero podría ser una trampa para autorizar una transacción maliciosa sin tu conocimiento. A lo largo de este artículo, desglosaremos en profundidad qué es el método personal_sign, cómo funciona su mecanismo de seguridad y por qué es una herramienta esencial para interactuar con el mundo descentralizado de manera segura.
- El Peligro Oculto: ¿Por Qué No Todos los Métodos de Firma Son Seguros?
- La Solución: El Prefijo de Seguridad de personal_sign
- Tabla Comparativa de Métodos de Firma
- Un Paso Más Allá: `eth_signTypedData`
- Verificación de la Firma: El Papel de `ecrecover`
-
Preguntas Frecuentes (FAQ)
- ¿Por qué nunca debería usar `eth_sign`?
- ¿Cuál es exactamente el propósito del prefijo "Ethereum Signed Message"?
- Entre `personal_sign` y `eth_signTypedData`, ¿cuál es mejor?
- ¿Puedo usar `personal_sign` para autorizar una transacción?
- ¿Cómo puede un desarrollador implementar la verificación de firmas?
- Conclusión
El Peligro Oculto: ¿Por Qué No Todos los Métodos de Firma Son Seguros?
Para apreciar la importancia de personal_sign, primero debemos entender el riesgo asociado con métodos más antiguos y menos seguros, como eth_sign. Durante mucho tiempo, eth_sign fue un estándar para firmar datos. Su funcionamiento es directo: toma un conjunto de datos, calcula su hash (utilizando el algoritmo Keccak-256) y luego firma ese hash con la clave privada del usuario.
El problema radica en su simplicidad. Dado que eth_sign firma un hash arbitrario, una DApp maliciosa podría construir una transacción válida de Ethereum, calcular su hash y presentárselo al usuario para que lo firme, disfrazándolo como un simple mensaje de inicio de sesión o un acuerdo de términos y condiciones. El usuario, al ver una cadena de caracteres hexadecimales que no puede interpretar, podría firmarla pensando que es inofensiva. Sin embargo, al hacerlo, estaría autorizando una transacción que podría vaciar su wallet. La firma resultante es indistinguible de la firma de una transacción real, lo que permite al atacante transmitirla a la red en nombre del usuario.
Este vector de ataque es extremadamente peligroso porque explota la falta de contexto en el proceso de firma. El usuario no tiene forma de saber que el hash que está firmando corresponde a una transacción, convirtiendo a eth_sign en una herramienta obsoleta y desaconsejada para la interacción con el usuario final.
La Solución: El Prefijo de Seguridad de personal_sign
Para mitigar este riesgo, se introdujo el método personal_sign. Su genialidad reside en un pequeño pero crucial añadido: un prefijo específico que se antepone al mensaje antes de ser hasheado y firmado. Este mecanismo asegura que la firma resultante nunca pueda ser confundida con la firma de una transacción de Ethereum.
El proceso de firma con personal_sign es el siguiente:
- Se toma el mensaje original que el usuario desea firmar.
- Se crea una nueva cadena de texto con el siguiente formato:
"\x19Ethereum Signed Message:\n" + longitud_del_mensaje + mensaje_original. - Esta nueva cadena completa (prefijo + longitud + mensaje) se hashea utilizando Keccak-256.
- El hash resultante es el que se firma con la clave privada del usuario.
El prefijo "\x19Ethereum Signed Message:\n" actúa como un dominio de firma claro e inequívoco. Cualquier aplicación o contrato inteligente que verifique esta firma sabe, sin lugar a dudas, que fue generada a partir de un mensaje destinado a ser firmado por un usuario y no a partir de una transacción. Esto rompe por completo el vector de ataque descrito anteriormente, ya que es imposible que una transacción de Ethereum, al ser hasheada, produzca el mismo resultado que un mensaje con este prefijo. Proporciona el contexto que faltaba, garantizando la seguridad del usuario.

Análisis de una Petición personal_sign
Las interacciones con un nodo de Ethereum se realizan a través de peticiones JSON-RPC. Una petición para usar personal_sign se vería así:
{ "id": 1, "jsonrpc": "2.0", "method": "personal_sign", "params": [ "0xdeadbeaf", "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" ]}
Desglosemos los parámetros (params):
- Parámetro 1:
"0xdeadbeaf"es el mensaje que se va a firmar, representado en formato hexadecimal. - Parámetro 2:
"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83"es la dirección de la cuenta (la wallet) que realizará la firma. Es crucial que esta cuenta esté desbloqueada en el cliente o monedero que se está utilizando.
El resultado de esta petición sería la firma digital:
{ "id": 1, "jsonrpc": "2.0", "result": "0xa3f20717a250c2b0b729b7e5becbff67fdaef7e0699da4de7ca5895b02a170a12d887fd3b17bfdce3481f10bea41f45ba9f709d39ce8325427b57afcfc994cee1b"}
Esta larga cadena hexadecimal es la firma, que puede ser utilizada para verificar que el propietario de la dirección mencionada efectivamente aprobó el mensaje "0xdeadbeaf".
Tabla Comparativa de Métodos de Firma
Para visualizar mejor las diferencias, aquí tienes una tabla comparativa entre los principales métodos de firma en Ethereum.
| Característica | eth_sign | personal_sign | eth_signTypedData |
|---|---|---|---|
| Nivel de Seguridad | Bajo (Vulnerable a suplantación de transacción) | Alto | Muy Alto |
| Datos Firmados | Hash arbitrario de 32 bytes. | Hash de un mensaje con prefijo específico. | Hash de datos estructurados y tipados. |
| Experiencia de Usuario | Pobre (muestra una cadena hexadecimal ininteligible). | Mejorada (puede mostrar el mensaje legible). | Óptima (muestra los datos de forma clara y estructurada). |
| Prevención de Replay Attack | No incorporada. | No incorporada. | Sí, mediante el uso de un dominio (chainId, verifyingContract). |
| Caso de Uso Recomendado | No recomendado para usuarios. Obsoleto. | Firma de mensajes de texto simples y seguros. | Firma de mensajes complejos y datos estructurados (ej. órdenes en un DEX). |
Un Paso Más Allá: `eth_signTypedData`
Aunque personal_sign es una mejora masiva en seguridad, todavía presenta un desafío: los usuarios a menudo tienen que firmar cadenas de datos hexadecimales que no entienden. Para abordar esto, se desarrolló eth_signTypedData. Este método permite firmar datos estructurados y tipados conforme al estándar EIP-712.
La principal ventaja es que las wallets pueden interpretar esta estructura y presentar los datos al usuario de una manera legible y comprensible. En lugar de ver "0xdeadbeaf", un usuario podría ver un mensaje claro como "¿Desea autorizar el inicio de sesión en la plataforma Ejemplo.com con su cuenta 0x...?" Esto reduce aún más la posibilidad de engaño y mejora drásticamente la experiencia del usuario.
Verificación de la Firma: El Papel de `ecrecover`
Una vez que se ha generado una firma, ¿cómo se puede verificar? En el contexto de los contratos inteligentes de Ethereum, la verificación se realiza utilizando una función precompilada llamada ecrecover. Esta función toma el hash del mensaje original (incluido el prefijo, en el caso de personal_sign) y la firma, y devuelve la dirección pública que generó dicha firma. Si la dirección devuelta coincide con la dirección del firmante esperado, la firma se considera válida. Este es el mecanismo que permite a las DApps confirmar la autenticidad de las acciones de un usuario.
Preguntas Frecuentes (FAQ)
¿Por qué nunca debería usar `eth_sign`?
No debes usar eth_sign porque firma un hash arbitrario sin contexto. Esto permite que un atacante te engañe para que firmes una transacción maliciosa pensando que es un mensaje inofensivo, lo que podría resultar en la pérdida de tus fondos.

¿Cuál es exactamente el propósito del prefijo "Ethereum Signed Message"?
Su propósito es actuar como un "espacio de nombres" o dominio de firma. Garantiza que la firma generada solo sea válida para un mensaje firmado por un usuario en Ethereum y no pueda ser reutilizada o confundida con una firma de transacción, evitando así ataques de suplantación.
Entre `personal_sign` y `eth_signTypedData`, ¿cuál es mejor?
Para firmar cadenas de texto simples, personal_sign es seguro y suficiente. Sin embargo, para datos más complejos o interacciones que involucren valores estructurados (como en DeFi o NFTs), eth_signTypedData es superior porque ofrece mayor claridad al usuario y previene ataques de repetición (replay attacks) entre diferentes DApps o cadenas.
¿Puedo usar `personal_sign` para autorizar una transacción?
No. El método está diseñado específicamente para NO ser compatible con el formato de firma de transacciones. Su propósito es la firma de mensajes, no la autorización de transferencias de fondos o ejecuciones de contratos en la cadena.
¿Cómo puede un desarrollador implementar la verificación de firmas?
Un desarrollador puede usar la función ecrecover dentro de un contrato inteligente en Solidity para verificar una firma on-chain. Fuera de la cadena (off-chain), se pueden utilizar bibliotecas de criptografía en lenguajes como JavaScript (ej. Ethers.js, Web3.js) para realizar la misma verificación.
Conclusión
La seguridad en el mundo de las criptomonedas es una responsabilidad compartida entre los desarrolladores que construyen las aplicaciones y los usuarios que interactúan con ellas. El método personal_sign es un pilar fundamental de esta seguridad, ofreciendo una forma estandarizada y segura de demostrar la propiedad de una cuenta sin exponer a los usuarios a los riesgos de la suplantación de transacciones. Al comprender cómo funciona y por qué es preferible a alternativas más antiguas como eth_sign, los usuarios pueden navegar por el ecosistema descentralizado con mayor confianza y proteger sus activos de manera más efectiva.
Si quieres conocer otros artículos parecidos a Personal_sign: La firma segura de Ethereum puedes visitar la categoría Seguridad.
