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

Rename "VerificationKey" to "JsonWebKey2020" #19

Closed
OR13 opened this issue Mar 23, 2020 · 11 comments
Closed

Rename "VerificationKey" to "JsonWebKey2020" #19

OR13 opened this issue Mar 23, 2020 · 11 comments

Comments

@OR13
Copy link
Contributor

OR13 commented Mar 23, 2020

@kdenhartog

We discussed maybe being able to use a key for both verification, and key agreement... and maybe with future suites as well...

Choosing something like JsonWebKey2020, might be more future facing... we could specify that JsonWebSignature2021 also supports JsonWebKey2020 keys... in the suite.

@OR13 OR13 changed the title Rename "VerificationKey" Rename "VerificationKey" to "JsonWebKey2020" Mar 23, 2020
@OR13
Copy link
Contributor Author

OR13 commented Mar 23, 2020

Related: w3c/did-core#185 (comment)

@kdenhartog
Copy link
Member

Thanks for filing this issue. Yes, I'd like to see us rename this key suite so that we can use JWKs and other representations (which may be out of scope for this repo) for multiple cryptographic algorithm suites.

After thinking about this further, ideally, I'd like to see key representation separated from the algorithms, and then referenced by cryptographic algorithms later. The purpose of the key represenation suites would be for highlighting how a key can be represented in different forms in JSON-LD.

E.g. a KeySuite2020 spec would define support for:

{
    "id": "did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
    "type": "JsonWebKey2020",
    "controller": "did:example:123",
    "publicKeyJwk": {
      "crv": "Ed25519",
      "x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ",
      "kty": "OKP",
      "kid": "_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"
     }
}

and additionally

{
    "id": "did:example:123456789abcdefghi#keys-2",
    "type": "Ed25519VerificationKey2018",
    "controller": "did:example:pqrstuvwxyz0987654321",
    "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}

I could see the spec additionally define support for how these keys are converted between each other.

@msporny
Copy link
Member

msporny commented May 26, 2020

Choosing something like JsonWebKey2020, might be more future facing... we could specify that JsonWebSignature2021 also supports JsonWebKey2020 keys... in the suite.

Big -1.

Making it easy to publish a publicKey with a 'd' field in it is the type of foot gun that we've successfully avoided for years in the Linked Data Security specs. Allowing it is an anti-pattern that should be avoided at all costs, there is just no good reason to do it.

@OR13
Copy link
Contributor Author

OR13 commented May 27, 2020

@msporny if you are using JWK and you don't know what d is.... thats like pretending to be a doctor and offering to do surgery... cryptography, like surgery or nuclear engineering, requires some competence to mitigate harm...

I feel that it's condescending to assume an absence of competence, especially w.r.t. established cryptography such as JOSE.

Maybe its because I had to go to school for this, and got told over and over again, don't roll your own crypto, don't use unpopular libraries, javascript is fundamentally unsafe, don't try and hack on crypto you are not familiar with outside of a research setting, etc...

JOSE uses the concept of "key" differently than what you believe is best... they define private key property name in a formal way: https://tools.ietf.org/html/rfc7518#section-6.2.2.1

in contrast, crypto-ld, and JSON-LD generally, don't even provide vocabulary definitions for privateKeyBase58 despite assuming the property to exist all over the place....

but privateKeyPem is defined....
https://github.com/w3c-ccg/security-vocab/blob/master/contexts/security-v1.jsonld#L38

Nothing stops a developer from doing this:

const { Ed25519KeyPair } = require('crypto-ld');
(async () => {
  const ed = await Ed25519KeyPair.generate();
  console.log(JSON.stringify(ed, null, 2));
//   {
//     "passphrase": null,
//     "type": "Ed25519VerificationKey2018",
//     "privateKeyBase58": "4N2xfkndpBLMjN9farAFVYpEibJeBMyj4YpT4WxbvkNZi2DMD9TmxuVQedXHSMxRCSB77Biqhwj2gxv6vigaDyix",
//     "publicKeyBase58": "E9ZKWeQMEP2GuGdDd4UTSziwmqFcHVzXPDACggB9dvwa"
//   }
})();

I think at the heart of this issue, is that JSON-LD security community has no common way of describing what a private key is, especially across representations... thats something which I am working on... but which is not the same as the question "How does JSON-LD security community represent JWKs"...

@msporny
Copy link
Member

msporny commented May 27, 2020

@msporny if you are using JWK and you don't know what d is.... thats like pretending to be a doctor and offering to do surgery... cryptography, like surgery or nuclear engineering, requires some competence to mitigate harm...

... and yet there aren't board certifications to use cryptography. It's illegal to pretend to be a doctor. It's not illegal to be a developer that accidentally misuses cryptography because they don't know any better.

This is the crux of the disagreement. There are many, many more developers that don't know what d is in JWK, and the dangers associated with it, than don't. It has been shown that developers regularly publish private keys, thinking that they're publishing public keys, with the 'd' parameter in place.

We should protect developers from this sort of stuff in the same way that we protect people in cars by giving them seat belts and airbags.

I'm saying, hey, you guys are building a car without seat belts and airbags, and I think that's a bad idea. So bad, that I'm trying to engage you on the topic and attempt to change your mind by drawing attention to what I believe to be a large blind spot in your thinking.

I feel that it's condescending to assume an absence of competence, especially w.r.t. established cryptography such as JOSE.

I make no value judgement on developers that don't know this stuff. In fact, quite the opposite, I empathize with them. As a developer, I don't want another developer to hand me a software library that is going to result in harm to me or my customers. I don't have the spare time to learn everything about everything. At some point, I have to trust that the people that build the standards and tools that I'm using help me get the job done, quickly and safely.

In short: Don't give me a foot gun.

Examples of cryptographic foot guns:

  • Allowing private keys to be accidentally published (e.g., publication of d).
  • Allowing public keys to be easily confused with private keys (e.g., merging VerificationKeys into PrivateKeys).

So, out of empathy for developers that don't have time to learn about this stuff (they have other more important things to do), we should be incredibly purposeful in how we design how these things are exposed and used.

/cc @kdenhartog @tplooker @dlongley @dmitrizagidulin @rhiaro

@OR13
Copy link
Contributor Author

OR13 commented May 27, 2020

Perhaps we can fix this issue by providing the following structure (with the appropriately crafted context behind it):

{
  "id": "did:example:123#fingerprint",
  "controller": "did:example:123",
  "type": ["PublicKey", "Ed25519VerificationKey2018"],
  "publicKeyBase58": "E9ZKWeQMEP2GuGdDd4UTSziwmqFcHVzXPDACggB9dvwa"
}
{
  "id": "did:example:123#fingerprint",
  "controller": "did:example:123",
  "type": ["PrivateKey"],
  "privateKeyBase58": "4N2xfkndpBLMjN9farAFVYpEibJeBMyj4YpT4WxbvkNZi2DMD9TmxuVQedXHSMxRCSB77Biqhwj2gxv6vigaDyix"
}
{
  "id": "did:example:123#fingerprint",
  "controller": "did:example:123",
  "type": ["Keypair"],
  "privateKeyBase58": "4N2xfkndpBLMjN9farAFVYpEibJeBMyj4YpT4WxbvkNZi2DMD9TmxuVQedXHSMxRCSB77Biqhwj2gxv6vigaDyix",
  "publicKeyBase58": "E9ZKWeQMEP2GuGdDd4UTSziwmqFcHVzXPDACggB9dvwa"
}

now replace publicKeyBase58 with publicKeyJwk and privateKeyBase58 with privateKeyJwk... and Ed25519VerificationKey2018 with JsonWebKey2020... and you have a single crypto suite that supports JOSE, and is much clearer than:

https://w3c-ccg.github.io/lds-ed25519-2018/#the-ed25519-key-format

Which is more of a footgun?

A home rolled crypto suite spec in the W3C CCG or a home rolled crypto suite spec in the W3C CCG that relies on a IANA for pretty much everything important?

For example, w3c-ccg/lds-ed25519-2018#1
Example is still out of date: https://w3c-ccg.github.io/lds-ed25519-2018/#example-2

I can see the argument that even building on JOSE is less secure than starting in a formally verifiable system like Coq or Agda and proving your way through OpenSSL... but thats also not a realistic solution for people who are trying to integrate with stuff that runs in the browser today: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey

Which Ed25519 does not.... in fact the only browser capable crypto suite that is defined was recently marked as deprecated due to being wildly out of date: https://github.com/w3c-ccg/lds-rsa2018

If this is mostly a documentation issue, I'm confident that the more documentation reuse we get (by supporting responsible algorithmic agility as JOSE does) the more contributors will show up to fix documentation.... If its a semantics issue, lets be more specific, lets define PrivateKey, PublicKey and Keypair formally for JWK and base58tc...

@kdenhartog
Copy link
Member

kdenhartog commented Jun 10, 2020

My take on this is less so about privateKeys and more so about the ability to reuse public key representations throughout multiple ld crypto suites. I'd even consider explicitly disallowing privateKeys to be included in JsonWebKey2020 for the exact reasons highlighted above or if representation of privateKeys are necessary defining it in such a way that they're defined as separate key suites.

However, I think my reason behind suggesting this change may have be misunderstood. Specifically, what I'm looking to do is elevate the purpose of a key to it's own layer within the ld-proof stack and allow representations (aka ed25519VerificationKey2018) to be reused throughout multiple crypto suites. This way rather than defining a separate key each time for each crypto suite, I can reference a selection of key representation suites while writing a specification for a crypto suite.

In past threads I've made mention of the ability to transform keys such as Ed25519 to X25519, or reusing P-256 for ECDSA and ECDH. However, nothing stops me from already doing that today and this change wouldn't prevent me from doing it tomorrow. By representing the same publicKey with a different type, an implementer can re-represent the same cryptographic material in a way that may be dangerous as it stands today. In other words, an implementer already has possession of the foot gun and they don't even know it. That's more the concern of cryptographers who conduct research on the algorithms and are developing the algorithms in my opinion and it's our jobs to relaying these concerns during the defining of the representations, so it's not misunderstood along the way.

That's not what we're doing here though. We're defining a representation, which in some cases can have overlaps with the concerns of cryptographers, and rather than defining that implementers shouldn't be doing this we're stating nothing about it. In those cases, I'd rather list these explicitly as security considerations in crypto suite specifications or publickey suite specification.

An example of a statement we might put in either Ed25519Signature2020 or Ed25519PublicKey2020 would be "Transformation of Ed25519 public keys into X25519 public keys has not been vetted as a secure reuse of cryptographic material. With this in mind, implementers SHOULD NOT reuse cryptographic material in Ed25519 public keys for the purposes of deriving an X25519 public key from the same cryptographic material." At least then we're being more clear about what an implementer should and should not do.

@OR13
Copy link
Contributor Author

OR13 commented Jun 11, 2020

JWK by default allows for custom properties... and its JSON-LD @type is @json... which Microsoft is already leveraging for commit / reveal strategies in Sidetree: decentralized-identity/sidetree#737

so, I'm not sure that banning d from makes any more sense than banning privateKeyBase58... unless we don't define these properties because we are relying on JSON-LD processing to drop them for security reasons... which is IMO, a totally terrible idea, because JSON-LD processing in different languages is now an attack vector..... there also appears to be a lot of redundancy in the way that LD Signature suites name things by convention today...

for example:

a key under assertionMethod with an type of Ed25519VerificationKey2018 and an attribute publicKeyBase58.... we basically just said "publicKey" 3 times, in 3 different ways... and while publicKeyBase58 makes it clear this is not a private key... there is nothing stopping someone from pasting a private key into its value, in much the same way that anybody could paste d into a JWK.

Settings that discussion aside... a major motivation for this crypto suite was to support JOSE, because its very popular, has lots of tooling in many different languages, and due to this, could be an easier path to adoption for LD crypto, since implementers need only tackle RDF Canonization / Linked Data concerns, not everything at once in a novel implementation in a new language.

JOSE defines key use here: https://www.iana.org/assignments/jose/jose.xhtml#web-key-use

so a JWK can be used for sig or enc... its not 2 different key types.... its 1 key type for 2 different uses.

Here is an example for P-384 https://en.wikipedia.org/wiki/P-384

A NIST Curve which might be required for certain work with governments...

it says that it supports both ECDSA and ECDH...

The proper way to represent this in a DID Document is as a JsonWebKey2020 verificationMethod with a reference to assertionMethod and keyAgreement.

If we want it to function like a jwk for use sig and enc... doing anything but this imposes uneeded, and politically dangerous burdens on JOSE developers we are attempting to encourage to support LD Crypto...

its one thing to ask them not to port over HS1 because its listed as prohibited... its another to tell them that a single key for 2 uses in JOSE must be represented as 2 different keys in JSON-LD, and that they need to document and register both in a system which takes months to review PRs... and which is controlled by a W3C community group: w3c-ccg/security-vocab#35

and that they are not allowed to use any of the other key types not registered under https://w3c.github.io/did-core/#dfn-publickey

Which is what we are implicitly doing by requiring this burdensome W3C registration process for each and every key type and purpose in the IANA registry: https://www.iana.org/assignments/jose/jose.xhtml#web-key-elliptic-curve

Do we want json-ld to work with legacy systems and gain valuable contributors or do we want to piss them all off by saying its an open world, but making the registration process impossible for things that they are required to use when working with governments or legacy systems?

The sooner JSON-LD works with JOSE, the sooner we can stop trying to get it to work and start working on base58 / multicodec / multibase stuff... because we know we will have things that cover our use cases, and we will have time to work on future facing crypto... This debate is blocking DIDComm and SDS, but I agree that we need to discuss it on a working group call and come to some kind of agreement regarding support for government requirements and legacy (but very popular) crypto systems.

@llorllale
Copy link

@OR13 when/will the LD crypto suite registry be updated to reflect this change?

@OR13
Copy link
Contributor Author

OR13 commented May 18, 2021

https://w3id.org/security/suites/jws-2020/v1

was created a weekend ago, the entire ld registry and did spec registries are currently still in the format they were when verification methods where in the did core context, and they both need to be updated.

@OR13 OR13 transferred this issue from w3c-ccg/lds-jws2020 Aug 5, 2022
OR13 added a commit that referenced this issue Aug 5, 2022
@OR13
Copy link
Contributor Author

OR13 commented Aug 9, 2022

This issue is stale, closing

@OR13 OR13 closed this as completed Aug 9, 2022
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

4 participants