Re: [webauthn] Add importCryptoKey input to PRF extension (#1945)

To summarize some of the discussion above, here's the rationale for which types of keys would be relevant to support:

- HMAC: no, because noone else would have the key.
- HKDF: no, because derived keys would still be extractable.
- PBKDF2: not applicable.
- AES: no, because encryption keys do not need to be protected from parties handling the cleartext (assuming each key is used for only one message).
- RSA (encrypt): yes, ignoring key size limitations.
- ECDH: yes, see below.
- RSA (sign): maybe - less useful than RSA (encrypt).
- ECDSA: maybe - less useful than ECDH.

As a concrete use case, I've recently been involved in a pilot project prototyping a web-based wallet app that uses WebAuthn PRF to derive encryption keys used to encrypt wallet contents. The current encryption architecture used in the pilot is described [here](https://open.gunet.gr/wallet-docs/docs/wallet/encryption-architecture). Aside from the self-critique already covered there, this app could benefit from having access to unextractable ECDH private keys.

It is possible with current PRF and WebCrypto capabilities to use RSA or ECDH for asymmetric encryption, so that one can have multiple PRF keys without having all of them present whenever encrypted content changes. But the drawback is that the asymmetric private keys are not hardware bound, and thus could be leaked if there's malicious script on the page. Leaking the asymmetric private keys is worse than leaking the encryption keys derived from them - whenever the encryption keys are in memory, the decrypted cleartext is too, but the encryption keys can be rotated frequently to protect future versions of the encrypted contents. Thus a leaked encryption key would give access only to one version of the encrypted data, which was already decrypted in memory at the time - but a leaked asymmetric private key would give access to all future versions as well.

A similar case could be made for RSA and ECDSA signing keys to sign arbitrary data, but this would not be useful for applications that need single-use signing keys for privacy. I plan to bring that use case up separately.

So, with this in mind, I think the most useful key types to support are ECDH and possibly RSA-OAEP. For that, I imagine the API could look something like this:

```
extensions: {
  prf: {
    eval: {
      first: new Uint8Array([1, 2, 3, 4]),
    },
    deriveCryptoKey:
      // EcKeyGenParams
      { name: "ECDH", namedCurve: "P-256" },

      // OR RsaHashedKeyGenParams
      { name: "RSA-OEAP", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" },
  }
}
```

where the client would then use the PRF output as a seed for deriving the private key by some deterministic procedure, for example that described in [NIST SP-800-56Ar3](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf) section 5.6.1.2.1 ([ECC] Key Pair Generation Using Extra Random Bits) (which seems similar to the [Montgomery reduction in BoringSSL linked above](https://github.com/w3c/webauthn/pull/1945#issuecomment-1709009190)?).

It may be that it's not appropriate to derive RSA keys from only 32 bytes of entropy, in which case ECDH would be the only valid key type.


-- 
GitHub Notification of comment by emlun
Please view or discuss this issue at https://github.com/w3c/webauthn/pull/1945#issuecomment-1746948875 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 4 October 2023 14:04:56 UTC