[BUG] When trying to verifyCredential or verifyPresentation, it fails with Error: wrong signature length.
ouoabcde opened this issue · comments
Current Behavior
I created vcJwt with createVerifiableCredentialJwt
and vpJwt with createVerifiablePresentationJwt
which are at did-jwt-vc
module. And I tried to verifyCredential
, verifyPresentation
which are at did-resolver
to verify vcJwt, vpJwt. But both fails at verifyJWT
->verifyJWSDecoded
->VerifierAlgorithm
->verifyES256K
->toSignatureObject
(these functions are in did-jwt
module.) with Error: wrong signature length.
Expected Behavior
verifyJWT
should pass with vcJwt and vpJwt.
Failure Information
It's error stack is described at Current Behavior section. I debugged why it failed and found that vcJwt, vpJwt which are created by createVerifiableCredentialJwt
and createVerifiablePresentationJwt
had 65 length signature when they are decodedJwt
. At toSignatureObject
, it checks that rawSig.length
is 65 when recoverable
is true, and if it's 64 when it's not recoverable. But always passing recoverable = false
which is default. vcJwt and vpJwt always failed verifying because their signature length were 65. So when I added toSignatureObject
function call with recoverable = true
at verifyES256K
function, the verification passed to both of them.
Steps to Reproduce
For example, just for vcJwt and verifyCredential,
- Create vcJwt with
createVerifiableCredentialJwt
. (did-jwt-vc) - Verify vcJwt with
verifyCredential
. (did-resolver) - You'll get
Error: wrong signature length.
error message.
There might be some confusion about the algorithms used for the JWT.
What parameters are you using for createVerifiableCredentialJwt
?
I used createVerifiableCredentialJwt(vcPayload, issuer)
. And my arguments were like below.
vcPayload
const myDid = "did:ethr:xxxx";
const claim = {
test: {
aaa: "aaa",
bbb: "bbb",
},
};
const vcPayload: JwtCredentialPayload = {
sub: myDid,
vc: {
"@context": ["https://www.w3.org/2018/credentials/v1"],
type: ["VerifiableCredential", "MyCustomCredential"],
credentialSubject: claim,
},
};
issuer
const issuer: Issuer = new EthrDID({
identifier: "my ethereum address",
privateKey: "my ethereum privatekey",
chainNameOrId: 5777
}) as Issuer;
I see,
It appears that there is indeed a mismatch between the default signing algorithm that EthrDID
uses for JWT (ES256K-R
) and the one that createVerifiableCredentialJwt
uses by default (ES256K
) if no algorithm is specified.
I suppose that the bug here is that createVerifiableCredentialJwt
simply assumes a default algorithm instead of complaining that there is none specified.
There are a few options to work around this issue.
- Let
createVerifiableCredentialJwt
know about the signer algorithm by specifying a header option:
const credential = await createVerifiableCredentialJwt(vcPayload, issuer, { header: { alg: 'ES256K-R' } })
- You can treat the
EthrDID
instance as anIssuer
and make it provide analg
:
const issuer: Issuer = new EthrDID({/*...*/}) as Issuer;
issuer.alg = 'ES256K-R' // add this line
This will let createVerifiableCredentialJwt
know which algorithm is actually in use.
- You can force your
EthrDID
instance to sign with a different signer (ES256K
):
import { ES256KSigner } from "did-jwt";
const signer = ES256KSigner("my ethereum privatekey", false);
const issuer: Issuer = new EthrDID({
identifier: "my ethereum address",
signer: signer, // initialize with a signer instead of a private key
chainNameOrId: 5777
}) as Issuer;
Thanks for the clear reason and the options to solve it. They all worked fine. So do you have plan to match the signing algorithm with EthrDID
?