transmute-industries / verifiable-data

Open Source Decentralized Identifiers and Verifiable Credentials Infrastructure and Tooling
https://transmute-industries.github.io/verifiable-data/smoke-test-react/
Apache License 2.0
52 stars 21 forks source link

Question: Ed25519VerificationKey2018 with publicKeyJwk #241

Closed strumswell closed 1 year ago

strumswell commented 1 year ago

From an external, we got a DID document with an Ed25519VerificationKey2018 where the public key is provided as a JWK (publicKeyJwk) which results in failed verifications of VCs signed by that particular key. After some debugging, I landed in the importFrom.ts inside ed25519-key-pair where based on the key type the correctly transformed/ decoded public key is returned (importFromType).

export const fromX25519KeyAgreementKey2019 = (
  k: Ed25519VerificationKey2018
): { publicKey: Uint8Array; privateKey?: Uint8Array } => {
  const publicKey = base58.decode(k.publicKeyBase58);
  let privateKey = undefined;
  if (k.privateKeyBase58) {
    privateKey = Uint8Array.from(base58.decode(k.privateKeyBase58));
  }
  return { publicKey, privateKey };
};

export const importableTypes: any = {
  JsonWebKey2020: fromJsonWebKey2020,
  Ed25519VerificationKey2018: fromX25519KeyAgreementKey2019,
};

export const importFromType = (k: any): any => {
  if (!importableTypes[k.type]) {
    throw new Error(
      `Cannot import from unsupported type: ${JSON.stringify(k, null, 2)}`
    );
  }
  return importableTypes[k.type](k);
};

Looking at this, Ed25519VerificationKey2018 is always expected to contain the public key encoded as Base58. Here is where you lose me. Is this a shortcoming of this library or is distributing the public key of an Ed25519VerificationKey2018 (encoded?) as a JWK nothing you (should) do?

Would love to get some clarification on that.

OR13 commented 1 year ago

Ed25519Signature2018 basically doesn't support jwk... Any library that wants to try key conversion can, we've tried to support both multiformats and JWK in some places, but it's a lot of work to support both.

I think in general its better to use JsonWebKey and JWTs, now that they preserve the JSON-LD data model.

OR13 commented 1 year ago

You can see what the authors of that suite intended to support here:

https://github.com/digitalbazaar/ed25519-signature-2018-context/blob/master/contexts/ed25519-signature-2018-v1.jsonld#L25

OR13 commented 1 year ago

Thank you for reporting this issue, feel free reopen or ask further questions, if you have them.

strumswell commented 1 year ago

Thanks for your super quick answer! I already had the feeling that the JSON-LD VC we got and the publicKeyJwk inside their issuers DID doc was rather "special". Concerning your tip around JsonWebKeys for JWTS: We're already enforcing JSON Web Signature 2020 for our ecosystem VPs and Ed25519 Signature 2018 for our ecosystem VCs. Sounds like we need to do the same for key types after seeing this. Thanks again for spoon feeding.

OR13 commented 1 year ago

Also a heads up https://github.com/w3c/vc-jws-2020

vdods commented 1 year ago

According to this, publicKeyBase58 is deprecated: https://www.w3.org/TR/did-spec-registries/#publickeybase58

I'm not sure what to make of this.

OR13 commented 1 year ago

Indeed, the working group had a lot of different RDF predicates for keys at one point.

They had:

publicKeyHex, publicKeyPem, publicKeyBase58 (btc), publicKeyJwk and publicKeyMultibase.

The only ones that survived to get commented on in the core spec (despite not being defined in the JSON-LD context)... are

publicKeyJwk and publicKeyMultibase.

I don't recommend using publicKeyMultibase, its a brand new key representation, its not an adopted standard... but it does have this registry if you want to make new key types:

https://github.com/multiformats/multicodec/pull/190

I tried to help them be compatible with IANA...

There is a lot of wheel reinventing here... for now a lot of value... I suggest you use JsonWebKey and publicKeyJwk.

OR13 commented 1 year ago

Related discussion happening right now:

https://github.com/w3c/vc-data-integrity/pull/99

in case you want to weigh in

vdods commented 1 year ago

Agreed on publicKeyJwk.

Just to clarify, when you say "I think in general its better to use JsonWebKey and JWTs, now that they preserve the JSON-LD data model", by "JsonWebKey" do you mean "JsonWebKey2020"?

OR13 commented 1 year ago

Yes, but beware that neither JsonWebKey2020 nor publicKeyJwk will be defined in the context... So you may need to do more JSON-LD if you want to process them as RDF... If you don't care about RDF you can just ignore the type completely.

strumswell commented 1 year ago

I am personally up for adoption of JsonWebKey2020/ publicKeyJwk as key types in our OCI specs @vdods. We need to discuss this in a bigger round deffo, as the Digital Wallet Conformance criteria still need heavy work around supported key types, signatures, and especially how the old spec writers were abusing the JWT spec/ fields. Our team will propose some changes in a few weeks as soon as everyone (and me :)) is back from vacation.


Also a heads up https://github.com/w3c/vc-jws-2020

Quickly looking at https://w3c.github.io/vc-jwt/ and did-jwt/ did-jwt-vc libs from DIF which we are using in Veramo: It looks like that official libs are not supporting this new spec yet, right? This would at least have an impact on the JWT header typ field and I guess on how the credential is embedded/ represented within the (decoded) JWT? I mean at least cryptographically should not change a lot here, as we have been using did-jwt/ did-jwt-vc and therefore JWS already?

Independent of that, I am not sure what adoption of JsonWebKey2020 would mean for our usage of did:ethr. We would at least have to submit a PR to do some kind of conversion of the current key type EcdsaSecp256k1VerificationKey2019 with its publicKeyHex in the DID doc. Seeing secp256k1 in here https://w3c.github.io/vc-jws-2020/#jose-conformance makes me think that this should be possible. And then I am still unsure what knock-on effects this would have during VP JWT issuance/ verification with the DIF libs.

OR13 commented 1 year ago

Yes, secp256k1 is supported in both JOSE and COSE.

Afaik, the DIF libs still only support v1.1.

The problem with v1.1 was that it blended JSON-LD and JOSE ways that broke both.

Off the shelf Jose libraries now work to support V2....

How you get the public key, was never defined in DIDs, but generally it's based on kid and iss.