Mensagem de erro
InvalidAccessError: Unable to use this key to verify
Texto do Node (sign gera “Unable to use this key to sign”, e uma chave de outro algoritmo gera “Key algorithm mismatch”). Os navegadores formulam de outro jeito — Chrome: “key.usages does not permit this operation”; Firefox: “A parameter or an operation is not supported by the underlying object”; Safari: “CryptoKey doesn't support verification” —, mas o nome da DOMException, InvalidAccessError, é o mesmo em todos.
WebCrypto crypto.subtle.sign / verify — browsers & Node
O que significa
O objeto de chave que você passou não tem permissão para executar esta operação: o array usages dela não inclui a operação, ou o tipo de chave está errado (verificar com uma chave privada, assinar com uma pública), ou a chave pertence a um algoritmo diferente do que a chamada pede. O material da chave pode ser perfeitamente válido — as permissões ou o papel dela é que não são.
Por que acontece
O array usages não incluía a operação na importação
comumAs chaves do WebCrypto seguem o princípio do menor privilégio: importKey(..., ["verify"]) produz uma chave que só pode verificar. Importar com [] ou com ["sign"] e depois chamar verify() falha aqui — os usos são fixados na criação e não podem ser acrescentados depois.
Metades pública e privada trocadas
comumO subtle.sign exige a chave privada; o subtle.verify exige a chave pública. Passar keyPair.publicKey para sign (ou privateKey para verify) é um erro de papel que a API recusa de imediato.
O algoritmo da chave difere do algoritmo da operação
ocasionalUma chave ECDH usada em uma chamada sign de ECDSA (ou vice-versa) falha mesmo na mesma curva — o WebCrypto vincula cada chave ao algoritmo para o qual ela foi criada, então arquiteturas do tipo “uma só chave EC para os dois” precisam importar o material duas vezes.
Como corrigir
- 1.
Declarar os usos de que você vai precisar
Liste todas as operações previstas ao gerar ou importar a chave; importe de novo o mesmo material com outros usos quando uma chave tiver vários papéis.
js const keyPair = await crypto.subtle.generateKey( { name: "ECDSA", namedCurve: "P-256" }, true, ["sign", "verify"], // privateKey gets "sign", publicKey gets "verify" ); - 2.
Passar a metade certa para cada chamada
Ao depurar, examine key.type e key.usages — eles dizem exatamente o que o objeto tem permissão para fazer.
js console.log(key.type, key.usages); // e.g. "public" ["verify"] const sig = await crypto.subtle.sign(alg, keyPair.privateKey, data); const ok = await crypto.subtle.verify(alg, keyPair.publicKey, sig, data);