Mensaje de error
invalid raw signature length
También se muestra como
- invalid raw signature length (argument="signature", value="0x…", code=INVALID_ARGUMENT, version=6.17.0)
- TypeError: invalid raw signature length
`err.shortMessage` es «invalid raw signature length»; `err.message` añade el argumento, el valor y la versión de ethers. El error es un `TypeError` con `code: "INVALID_ARGUMENT"`.
ethers v6 (JavaScript) — Signature.from() inside verifyMessage / verifyTypedData / recoverAddress
Qué significa
ethers intentó interpretar los bytes de la firma como una firma ECDSA para recuperar la dirección, y la longitud no encaja en ninguna de las formas que conoce: 65 bytes (r‖s‖v) o 64 bytes (la forma compacta de EIP-2098). No se intentó ninguna recuperación. Normalmente, los bytes son un tipo de firma completamente distinto: una firma de cuenta inteligente que hay que comprobar en cadena o una firma codificada en DER de un servicio de gestión de claves.
Por qué ocurre
Una firma de billetera de contrato inteligente
frecuenteSafe, Coinbase Smart Wallet, Argent y otras cuentas ERC-4337 devuelven firmas que solo el contrato de la cuenta puede validar (ERC-1271), a menudo envueltas según ERC-6492 en el caso de cuentas aún no desplegadas. Miden cientos de bytes y no se pueden verificar con `verifyMessage`.
Una firma DER de AWS KMS o Google Cloud KMS
frecuenteLas claves `ECC_SECG_P256K1` de AWS KMS y `EC_SIGN_SECP256K1_SHA256` de Google Cloud KMS devuelven ASN.1 DER (70–72 bytes) sin ID de recuperación. Primero hay que convertirlo a r‖s‖v.
Truncada o codificada dos veces
ocasionalUna firma cortada en una columna de la base de datos, el hex de una cadena hex o un valor que perdió su último byte al guardar `v` por separado.
Cómo solucionarlo
- 1.
Verificar las cuentas inteligentes en cadena
Llama a `isValidSignature` (ERC-1271) en la cuenta, o usa una biblioteca que implemente ERC-6492 para cuentas contrafactuales (por ejemplo, `verifyMessage` de viem con un cliente público).
js import { Contract, hashMessage, JsonRpcProvider } from "ethers"; // Smart accounts (Safe, Coinbase Smart Wallet, ERC-4337 accounts) are verified on-chain (ERC-1271). const provider = new JsonRpcProvider(process.env.RPC_URL); const account = new Contract(address, ["function isValidSignature(bytes32,bytes) view returns (bytes4)"], provider); const magic = await account.isValidSignature(hashMessage(message), signature); const valid = magic === "0x1626ba7e"; - 2.
Convertir DER a r‖s‖v
Extrae r y s, normaliza s a la mitad inferior del orden (Ethereum rechaza los valores high-s) y prueba los dos bits de recuperación para encontrar el que da la dirección esperada.
js import { Signature, recoverAddress, hashMessage, toBeHex } from "ethers"; import { secp256k1 } from "@noble/curves/secp256k1.js"; // @noble/curves v2 const N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n; // secp256k1 order // KMS/HSM: parse DER, move s to the lower half (Ethereum rejects high-s), then find the recovery bit. function derToEthSignature(derBytes, digest, expectedAddress) { const { r, s } = secp256k1.Signature.fromBytes(derBytes, "der"); const lowS = s > N / 2n ? N - s : s; for (const yParity of [0, 1]) { const candidate = Signature.from({ r: toBeHex(r, 32), s: toBeHex(lowS, 32), yParity }); if (recoverAddress(digest, candidate) === expectedAddress) return candidate.serialized; // 65 bytes } throw new Error("signature does not belong to " + expectedAddress); } const signature = derToEthSignature(kmsDer, hashMessage(message), kmsAddress);