Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Key Type #7

Closed
David-Chadwick opened this issue Dec 21, 2019 · 19 comments
Closed

Key Type #7

David-Chadwick opened this issue Dec 21, 2019 · 19 comments

Comments

@David-Chadwick
Copy link

I would like to suggest that did:key supports different key types. Two key types have already been identified:

  • jwt keys
  • dlt keys

the structure would therefore become

did:key:<type>:<type specific key encoding

For the jwt type I would like to suggest the following encoding

did:key:jwt:<base 64 encoded public key>

Note that the algorithm id is not needed in the jwt key encoding because this is already included in the JWT header in its own alg parameter

For the dlt type this would follow the encoding specified in the draft by @msporny i.e. the key and algorithm are encoded together using base58 encoding

@dlongley
Copy link
Contributor

@David-Chadwick,

Could you provide a problem statement and use case for when this new type is needed? That would help us explore whether or not there may be other ways to solve the problem.

I ask because, unfortunately, this would have the effect of creating two different DIDs for the same keys. On its own this isn't necessarily a problem, but I would expect some users to want to reuse the same DID with different key formats (depending on application) -- and this may coerce them to use two different identifiers when all they really want is two different key formats. This could lead to a number of maintenance issues and annoyances.

As an alternative, if additional key formats are desired, we could also include those formats in the resolution process, such that the resulting DID Document expresses them. For example, adding JWK would make it such that the resolved DID Document looks like this:

{
  "@context": "https://w3id.org/did/v1",
  "id": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH",
  "publicKey": [{
    "id": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH#pubkey",
    "type": "Ed25519VerificationKey2018",
    "controller": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH",
    "publicKeyBase58": "B12NYF8RrR3h41TDCTJojY59usg3mbtbjnFs7Eud1Y6u",
    "publicKeyJwk": { /* JWK here */ }
  }],
  "authentication": [ "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH#pubkey" ],
  "assertionMethod": [ "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH#pubkey" ],
  "capabilityDelegation": [ "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH#pubkey" ],
  "capabilityInvocation": [ "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH#pubkey" ],
  "keyAgreement": [{
    "id": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH#kakey",
    "type": "X25519KeyAgreementKey2019",
    "controller": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH",
    "publicKeyBase58": "JhNWeSVLMYccCk7iopQW4guaSJTojqpMEELgSLhKwRr",
    "publicKeyJwk": { /* JWK here */ }
  }]
}

Any other desirable formats could be done the same way. But I don't know precisely what your problem/use case is so I don't know if this would solve it whilst avoiding the issue I mentioned.

@David-Chadwick
Copy link
Author

The use case is simple. When users are identified by their public keys then credentialSubject.id needs to be a public key. When JWT is used to sign VCs (and VPs) prior to transfer, the JWT header holds the algorithm id and the key id as separate claims. Thus there is no requirement to encode the algorithm id along with the key id, as we already know the algorithm id. Secondly, JWT already uses base64 encoding so there is no requirement to use an alternative encoding such as base58. Finally there is no requirement to expand the key id into a DID document as you are doing in your example above. All the verifier needs to do is base64 decode the received key id in order to validate the signature.
Conclusion. The existing did:key encoding scheme is too complex and unnecessarily so for JWT signing. A much simpler encoding scheme is needed.

@David-Chadwick
Copy link
Author

One final point. These keys are ephemeral keys that are only used for point to point communications, so there is no danger that they would necessitate the creation of two different DIDs for the same key pair since they are only used for one purpose.

@OR13
Copy link
Contributor

OR13 commented Jan 6, 2020

Seems others have thought about this already...

https://github.com/uport-project/nacl-did

https://github.com/OnePair/node-did-jwk

https://github.com/transmute-industries/did-jose

^ I'm the author of the last one....

We could add an encoding bit to the did key that specified that what follows is a serialized jwk... it makes the did large, but it automatically supports all of JOSE.... This would also let you use did;key for nonextractable keys in the browser, and of course all of Suite B / NIST Curves, legacy crypto, etc...

@OR13
Copy link
Contributor

OR13 commented Jan 6, 2020

I'd like to see an approach that defines an umbrella for all these deterministic did documents... I don't want to have to support N different deterministic transformations of a public key to did document...

I feel like with a simple encoding table, this can be achieved...

@David-Chadwick
Copy link
Author

David-Chadwick commented Jan 6, 2020

The approach we have taken in our latest implementation is to use did:key:jwt and then base64 encode the type values specified in RFC 7517. This would seem to be as near to a standards based approach as possible.

@TallTed
Copy link

TallTed commented Jan 6, 2020

did🔑jwt

I think you meant did:key:jwt ... which github's markdown interpreter changed to include the :key: emoji (🔑)...

(More stuff to try to remember to codefence in github comments, like all the @things.)

@OR13
Copy link
Contributor

OR13 commented Jan 6, 2020

So did:key:jwt:<encoded> where <encoded> is:

JWT(header, payload=JWK, signature) ?

I like this a lot more than what I implemented in my hacky did-jose example.

@msporny
Copy link
Contributor

msporny commented Jan 6, 2020

I like this a lot more than what I implemented in my hacky did-jose example.

This makes no sense to me... do you guys mean did:jwk? Why do you need to encode a jwt as a did:key?

@OR13 wrote:

I'd like to see an approach that defines an umbrella for all these deterministic did documents... I don't want to have to support N different deterministic transformations of a public key to did document.

I don't understand what the above means... are you saying that because keys can be expressed as JWKs, that we should just use that instead of multikey (which would then require you to pull in the entire JOSE stack, or at least a JWK library)?

@David-Chadwick
Copy link
Author

@manu. We are already using a jwt library to sign and verify our VCs. So we dont need to pull in anything else. The only JWK parameters we need in the did are the alg parameter (in our case either RS256 or ES256) plus the variables (for RSA this is e and n; for EC it is x and y). So the key encoding is quite compact and allows any recipient that knows what the fixed parameters/meanings of RS256 or ES256 are, to be able to verify the signature. I think this fits neatly with the use of JWT/JWS to sign VCs.

@OR13
Copy link
Contributor

OR13 commented Jan 7, 2020

@msporny

I don't understand what the above means... are you saying that because keys can be expressed as JWKs, that we should just use that instead of multikey (which would then require you to pull in the entire JOSE stack, or at least a JWK library)?

I don't want to see a proliferation of DID Methods that are just deterministic transformations of public key material.

I'd rather see a way to make did:key define its self such that no other methods would be needed.

I have a transformation I use to extend did:key with jwk today, which works fine for me, but it sorta breaks the concept of did:key because software implementations become hard coupled to the transformed document, not the actual Method Spec compliant document... thats what I want to avoid, by making did:key Method Spec, account for these cases, such that there is no need to use transforms and hard couple to transforming resolvers, but of course that is a solution as @dlongley noted above.

To be extra clear, I don't think we need a did:jwk at all.

We either transform did:key and hard couple to the transformer.

Or extend it with something like did:key:<jwk|jwt>:...

@OR13
Copy link
Contributor

OR13 commented Mar 3, 2020

Cross linking: digitalbazaar/did-method-key#3

@OR13
Copy link
Contributor

OR13 commented Mar 4, 2020

We should close this issue / disable any further discussion here if the repo is going to be deleted. I tried to preserve some of this history here: digitalbazaar/did-method-key#3

Next time lets move things over quickly / not create a git issue like this :)

@OR13 OR13 transferred this issue from another repository Mar 4, 2020
@OR13 OR13 transferred this issue from w3c-ccg/community Mar 4, 2020
@OR13
Copy link
Contributor

OR13 commented Mar 5, 2020

This issue has been moved around a bit, but its safe to comment on again :)

Linking the discussion from the JS implementation as its relevant to the did method spec: digitalbazaar/did-method-key#8

Essentially, I would like to be able to support hd-wallet systems with did:key :)

@OR13 OR13 mentioned this issue Mar 5, 2020
@OR13
Copy link
Contributor

OR13 commented Aug 2, 2020

@David-Chadwick @msporny @dlongley We need to address this issue, its been open for ages...

First, the current spec relies on multiformats for encoding public key bytes...@David-Chadwick wants to use a self attested JWT of a JWK instead... something like:

did:key:JWT

Where JWT is some kind of self signed JWK.

There are a couple problems with this approach.

  1. There is no canonical representation for JWKs (multiple identifiers for the same public key bytes).
  2. There is no need to provide an assertion (the public key bytes would be enough, you don't need a signature).

Based on these points, I would recommend the following:

Option 1

We close this issue, and @David-Chadwick creates a new DID Method for what he wants to do.... I would recommend creating a spec that generates canonical JWKs using JCS and then just do something like:

did:jwk:base64url(cannonical(JWK))

Option 2

We agree to extend DID Key with something like option 1....

I an in favor of just doing option 1, somewhere else... especially after spending as much time with canonical JSON in sidetree as I have.... asking for a did key as a JWK seems like for of a job for resolver options than a did param or an entire alternate encoding for a did method.

@David-Chadwick
Copy link
Author

David-Chadwick commented Aug 2, 2020 via email

@msporny
Copy link
Contributor

msporny commented Aug 3, 2020

I an in favor of just doing option 1

I am as well, after having looked into this a bit adding a JWK representation pulls in a kitchen sink of JOSE dependencies into did:key (which we're trying to avoid). I had played around with the idea of making did:key:jwk optional, as in, a did:key implementation doesn't have to support it, but if it does... then it does what you propose above. That could be an acceptable compromise, or, as @OR13 suggests, we just do did:jwk elsewhere due to the complexity (and we could easily have mappings between the multicodec did:key and JOSE did:jwk.

I've been holding back wrt. saying this until we had a did:key:jwk implementation under our belts and could then understand the fullness of the concern I outline above. We've only spent a day here and there exploring it... that none of our customer systems have needed JWK yet is telling (at least, internally).

In any case, +1 to @OR13's suggestion. We like the direction that the JwsSignature2020 (and family) stuff is going in, so if we can do the same for did:jwk, that'd be ideal. Then we'd have a clear line between "the way things have been done" and "a potentially better way to do things".

@OR13
Copy link
Contributor

OR13 commented Aug 3, 2020

@David-Chadwick I suggest you link to a spec for did:jwk / what you are currently doing, and we close this issue.

if you are indeed not worried about multiple ids for the same key type, that seems like a fundamental incompatibility with the mental model of did:key... however.. its entirely equivalent to what I did with did:meme... you can have multiple dids (memes) for the same public key bytes.... there are privacy advantages to that approach which you should be free to explore in a separate spec :)

@OR13
Copy link
Contributor

OR13 commented Aug 24, 2020

I am closing this issue, I would happily review a PR to add an information reference to whatever comes of it down the road to the did key method spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants