Message d’erreur
invalid raw signature length
Également affiché sous la forme
- invalid raw signature length (argument="signature", value="0x…", code=INVALID_ARGUMENT, version=6.17.0)
- TypeError: invalid raw signature length
`err.shortMessage` vaut « invalid raw signature length » ; `err.message` y ajoute l’argument, la valeur et la version d’ethers. L’erreur est une `TypeError` avec `code: "INVALID_ARGUMENT"`.
ethers v6 (JavaScript) — Signature.from() inside verifyMessage / verifyTypedData / recoverAddress
Ce que cela signifie
ethers a tenté d’interpréter les octets de la signature comme une signature ECDSA pour récupérer une adresse, et leur longueur ne correspond à aucune des formes qu’il connaît : 65 octets (r‖s‖v) ou 64 octets (la forme compacte EIP-2098). Aucune récupération n’a été tentée. Ces octets sont généralement un tout autre type de signature : une signature de compte intelligent, qui doit être vérifiée sur la blockchain, ou une signature encodée en DER provenant d’un service de gestion des clés.
Pourquoi cela se produit
Une signature de portefeuille de contrat intelligent
fréquenteSafe, Coinbase Smart Wallet, Argent et d’autres comptes ERC-4337 renvoient des signatures que seul le contrat du compte peut valider (ERC-1271), souvent enveloppées selon ERC-6492 pour les comptes pas encore déployés. Elles font des centaines d’octets et ne peuvent pas être vérifiées avec `verifyMessage`.
Une signature DER issue d’AWS KMS ou de Google Cloud KMS
fréquenteLes clés `ECC_SECG_P256K1` d’AWS KMS et `EC_SIGN_SECP256K1_SHA256` de Google Cloud KMS renvoient de l’ASN.1 DER (de 70 à 72 octets) sans identifiant de récupération. Il faut d’abord le convertir en r‖s‖v.
Tronquée ou encodée deux fois
occasionnelleUne signature tronquée dans une colonne de base de données, l’encodage hexadécimal d’une chaîne déjà en hexadécimal, ou une valeur qui a perdu son dernier octet quand `v` a été stocké séparément.
Comment corriger l’erreur
- 1.
Vérifier les comptes intelligents sur la blockchain
Appelez `isValidSignature` (ERC-1271) sur le compte, ou utilisez une bibliothèque qui implémente ERC-6492 pour les comptes contrefactuels (par exemple `verifyMessage` de viem avec un client public).
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 le DER en r‖s‖v
Analysez r et s, normalisez s dans la moitié inférieure de l’ordre (Ethereum rejette les valeurs high-S), et essayez les deux bits de récupération pour trouver celui qui donne l’adresse attendue.
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);