W3C home > Mailing lists > Public > public-credentials@w3.org > June 2020

Re: Fwd: Verifying JWT Verifiable Credentials

From: David Chadwick <D.W.Chadwick@kent.ac.uk>
Date: Wed, 10 Jun 2020 09:42:15 +0100
To: Dominic Wörner <dom.woe@gmail.com>, "public-credentials@w3.org" <public-credentials@w3.org>
Message-ID: <f5b2a274-528f-b38a-41c1-1bf45c78e2f0@kent.ac.uk>
Hi Dominic

we dont believe you need DID documents in order to use JWT crypto to 
protect VCs. The JWT kid allows you to directly encode the public key so 
that the JWT is self contained and allows you to verify the signature of 
the JWT without any external lookups. Here is how we do it in a 
standards conformant way:

We base64 encode the signer's public key using RFC 7517 Appendix A.1


The ‘kid’ is created according to RFC 7517 and comprises the algorithm 
id, and the public key parameters (for RSA this is the modulus,n, and 
the exponent,e, and for ECDSA this is the x and y co-ordinates of the 
base point).


An example encoding for RS256 is:

"n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx

4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSocBJECPebWKRXjBZCiFV4n3oknjhMs

tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2

QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI

SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-GxBniIqb

w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",

"e":"AQAB",

"alg":"RS256"

And for EC256 is:

"x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",

"y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",

"alg":"ES256"

This allows you to verify the signatures on both the VP and the VC. Note 
that it does not solve the trust issue. How you decide which issuers to 
trust is a separate issue and should be configured out of band.

Kind regards

David

On 10/06/2020 08:30, Dominic Wörner wrote:
> Thanks Orie for the detailed response.
>
> Could you try explain how you distinguish Vanilla JWS and VC-JWT? It 
> could be that my reply below is confused because I don't really 
> understand the terms you use.
>
> If I get the following;
> If its a vanilla JWS (not a VC-JWT) check the JWS header for `kid`... 
> if its a VC-JWT, check the payload `iss` or `vc.iss`... figure out 
> which did is the issuer... resolve the issuer did... or `kid`.
> Then you argue, one should not use the `kid` in the JWT header in the 
> case of VC-JWT.
> Although the following is written in the VC-JWT Spec:
> |kid|/MAY/ be used if there are multiple keys associated with the 
> issuer <https://www.w3.org/TR/vc-data-model/#dfn-issuers> of the JWT. 
> The key discovery is out of the scope of this specification. For 
> example, the |kid| can refer to a key in a DID document 
> <https://www.w3.org/TR/vc-data-model/#dfn-decentralized-identifier-documents>, 
> or can be the identifier of a key inside a JWKS.
>
> This approach is also used in the example of the domain linkage 
> credential at DIF: 
> https://identity.foundation/.well-known/resources/did-configuration/#json-web-token-proof-format
>
> I don't get the following:
> If its a VC-JWT, search assertionMethod for the public key to verify
> I thought assertionMethod is a term used by LD Signatures and don't 
> appear in VC-JWT ?!
>
> Thanks a lot!
>
> Best,
> Dominic
>
>
> Am Di., 9. Juni 2020 um 21:42 Uhr schrieb Orie Steele 
> <orie@transmute.industries>:
>
>     There is no consensus on key resolution for JWT with VC Data
>     Model.... it's been a huge problem, and has been discussed many
>     times... We were finally able to add this language to did core,
>     which hints at a standard way of resolving a public key from a kid...
>
>     It is RECOMMENDED that JWK kid values are set to the public key
>     fingerprint. It is RECOMMENDED that verification methods that use
>     JWKs to represent their public keys utilize the value of kid as
>     their fragment identifier. See the first key in EXAMPLE 15 for an
>     example of a public key with a compound key identifier.
>
>     https://w3c.github.io/did-core/#example-15-various-public-keys
>
>     however the value of kid in the JWS can either be
>     `did:example:123#kid` or `kid`... I strongly urge everyone to use
>     `did:example:123#kid` and not rely on an undocumented / non
>     standard combination of `iss` and `kid`... unlike JWT in OAuth...
>     there is no spec for doing what did-jwt does... consider also that
>     `iss` and `vc.issuer` might both be used, or only 1 might be
>     used... because VC-JWT says:
>
>     For backward compatibility with JWT processors, the following
>     JWT-registered claim names MUST be used *instead of, or in
>     addition to*, their respective standard verifiable credential
>     counterparts
>
>     So semi-safe verify JWS from a did logic logic based on did-core
>     and vc-data-model today looks like this:
>
>     If its a vanilla JWS (not a VC-JWT) check the JWS header for
>     `kid`... if its a VC-JWT, check the payload `iss` or `vc.iss`...
>     figure out which did is the issuer... resolve the issuer did... or
>     `kid`.
>
>     If its a vanilla JWS, search all the
>     https://w3c.github.io/did-core/#verification-relationships for the
>     public key to use to verify.
>
>     If its a VC-JWT, search assertionMethod for the public key to verify
>
>     If its a VP of a VC-JWT also encoded as a JWT, search
>     authentication for the key to verify...
>
>     Someday, we will have this documented somewhere... and we can just
>     reference it... I think it's high time we updated the
>     vc-data-model to explain how to use VC-JWT correctly, and in
>     particular how to use JWS / JWE with DIDs... when the payload IS
>     NOT a VC.
>
>     OS
>
>     On Tue, Jun 9, 2020 at 7:52 AM Dominic Wörner <dom.woe@gmail.com
>     <mailto:dom.woe@gmail.com>> wrote:
>
>         Hi,
>
>         We currently work with JWT VC because of the lack of proper
>         JSON-LD tooling in Java.
>         The iss property of VCs is a DID and I have a question on the
>         verification algorithm since it's not well defined in the data
>         model spec because it is out of scope.
>
>         After reading the spec, we implemented the following approach:
>
>         * Resolve issuer DID
>         * If kid in header then get pubkey with kid form did doc. If
>         not found => abort
>         * If no kid in header then there must be only one public key
>
>         Now, I've looked at the code of
>         https://github.com/decentralized-identity/did-jwt
>         There the following approach is taken (if I'm correct)
>
>         * Resolve issuer DID
>         * Get authenticators (pub keys referenced in authentication
>         array in DID doc)
>         * Try all authenticators. Fail only of none of the
>         authenticators work
>
>         I don't think the library handles the usage of a kid in the
>         header.
>
>         This leaves me with the question, is there consensus about the
>         approach taken in did jwt? ;)
>         * Public Keys to verify VCs, need to be referenced in the
>         authentication block of the DID doc
>         * It's not required to reference a specific key in the VC if
>         there are multiple keys in the DID doc?
>
>         I can see that the second point has some advantages. Given I
>         have a DID doc with a single public key and I create a VC
>         without specifying the kid, I would invalidate the VC by
>         adding another key to the DID doc, if the verifier would not
>         try all keys.
>
>         Best,
>         Dominic
>
>
>
>     -- 
>     *ORIE STEELE*
>     Chief Technical Officer
>     www.transmute.industries
>
>     <https://www.transmute.industries>
>
Received on Wednesday, 10 June 2020 08:42:32 UTC

This archive was generated by hypermail 2.4.0 : Wednesday, 10 June 2020 08:42:33 UTC