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

Evidence that kty: PQK + alg is the path forward #50

Open
OR13 opened this issue Mar 20, 2022 · 0 comments
Open

Evidence that kty: PQK + alg is the path forward #50

OR13 opened this issue Mar 20, 2022 · 0 comments

Comments

@OR13
Copy link
Collaborator

@OR13 OR13 commented Mar 20, 2022

I did yet another JWT / CWT library integration with DIDs this weekend, I wrote the same "alg" detection code I have written every time I have reached for JOSE and COSE...

https://github.com/transmute-industries/verifiable-data/blob/main/packages/did-jose-cose/src/keyPairToAlg.ts

Just so its clear this isn't just me...

https://github.com/panva/jose/blob/6b5e6acbe4c380b6b1142e3fbfc33a664552a272/src/jwks/local.ts#L18

https://github.com/panva/jose/blob/80741cb32a5b34d40c89478e2fdd0b4116eda546/src/runtime/node/node_key.ts#L21

Pretty much every JOSE / COSE library has some mapping like this because:

  1. alg is optional in JWK
  2. importing a key without specifying an alg makes it impossible to know which signature scheme the key is supposed to be used with.

Let's say you want to use an off the shelf JOSE library to sign with a spec legal JWK private key....

You will be doing something like this:

import { keyPairToAlg } from "../../keyPairToAlg";
import { CompactJwt, PrivateKeyJwk, Header, Payload } from "types";
const jose = require("jose");
export const sign = async (
  header: Header,
  payload: Payload,
  privateKeyJwk: PrivateKeyJwk
): Promise<CompactJwt> => {
  const alg = keyPairToAlg(privateKeyJwk);
  const jwt = await new jose.SignJWT({ ...payload })
    .setProtectedHeader({ alg, ...header })
    .setIssuedAt(payload.iat)
    .setIssuer(payload.iss)
    .setAudience(payload.aud)
    .setExpirationTime(payload.exp)
    .sign(await jose.importJWK({ alg, ...privateKeyJwk }));
  return jwt;
};

If privateKeyJwk had an alg (even though its optional, you are good).

If privateKeyJwk did not have an alg (likely given its optional), you will be asking the caller to

  1. "know the legal algs, and ask for the right one or get an error"
  2. "have the library compute the legal alg from the key (as shown above)"

Both are a source of security bugs that can be catastrophic...

In general, a single key shall be used for only one purpose (e.g., encryption, integrity
authentication, key wrapping, random bit generation, or digital signatures).

Cryptography can be rendered ineffective by the use of weak products, inappropriate algorithm
pairing, poor physical security, and the use of weak protocols.

see also "5.6.4 Transitioning to New Algorithms and Key Sizes"... impossible to do with some spec legal JWK.

The current spec legal interpretation of JOSE / COSE for OKP and EC crv + alg pairings violates security best practices.

Making alg optional was a mistake... its not too late to fix this for post quantum keys.

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

1 participant