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

Bug 27774 - The KDFs either shouldn't allow importing extractable keys, or should support exportKey() #76

Closed
mwatson2 opened this issue May 24, 2016 · 16 comments
Assignees

Comments

@mwatson2
Copy link
Collaborator

Bug 27774:

There is currently an awkward interaction for how import/export works for the KDFd (PBKDF2, HKDF, Concat-KDF):

  • You can importKey(extractable=true), however the exportKey() operation is not supported. So in truth you can never actually export these keys. It is less then ideal to accept extractable=true during import, but create a key which is effectively unextractable.
  • You can unwrapKey() for the KDFs (because they support the importKey() operation), however the converse is not true (you cannot wrapKey() because exportKey() is unsupported). It is strange that you could unwrap something (perhaps created directly using encrypt()), but cannot directly wrap it. (If you wrap will get NotSupportedError)

I think the most consistent behavior would be to simply define exportKey() operation for these algorithms. Let callers specify extractable=false if they want to forbid extractability, and keep the API working in a predictable manner.

Alternately maybe extractable=true should be forbidden during key import. However that feels kludgey in its own way.

Other suggestions?

@sleevi
Copy link
Contributor

sleevi commented May 24, 2016

I do not thing symmetry should trump sanity here. The KDFs' importKey operations should make extractable=false, and neither should allow the raw state from the KDF. If you want the raw state, it can be obtained from the algorithm chaining to the KDF.

@mwatson2
Copy link
Collaborator Author

@jimsch wrote:

I cannot think of a use case where the ability to do the export of the key for a KDF function is useful. However, I would agree that in this case symmetry makes sense.

@mwatson2
Copy link
Collaborator Author

The options here appear to be either to require extractable to be false for importKey() for HKDF-CTR and PBKDF2 or to support exportKey() for those algorithms.

@jimsch
Copy link
Collaborator

jimsch commented May 26, 2016

I have a vague preference to require extractable to always be false rather than requiring support for exportKey(), but it is not a very strong preference.

@sleevi
Copy link
Contributor

sleevi commented May 26, 2016 via email

@bdhess
Copy link
Contributor

bdhess commented Jun 6, 2016

+1 for extractable = false

@mwatson2 mwatson2 self-assigned this Jun 8, 2016
mwatson2 added a commit to mwatson2/webcrypto that referenced this issue Jul 11, 2016
@mwatson2
Copy link
Collaborator Author

PR #113

@engelke
Copy link

engelke commented Jul 13, 2016

The PR looks good to me.

@ghost
Copy link

ghost commented Mar 25, 2022

I'm trying to understand the reasoning behind not allowing extractable=true for KDF key imports.

As far as I understand, none of the major implementations of crypto.subtle.generateKey() support generating HKDF or PBKDF2 keys, so a raw KDF key has to be imported through crypto.subtle.importKey(). As such, the raw KDF key is already conveniently available to the application programmer, which leads to the question of what can be gained by requiring extractable=false for KDF key imports?

On the other hand, there are legitimate use cases where one would want to export the KDF key. By enforcing this requirement, the ability to conveniently convert IKM into base64url (jwk) format is lost...

Am I missing something?

@twiss
Copy link
Member

twiss commented Mar 25, 2022

@beebeetles The main other way to get a KDF key is via deriveKey. If you call deriveKey(extractable=true) and then call exportKey on it (which today is also not supported, but let's say it was), then this is essentially equivalent to calling deriveBits, and that should be used instead (and the key usages should contain deriveBits, to permit this). That's why the former was prohibited, I believe.

@ghost
Copy link

ghost commented Mar 25, 2022

@twiss I'm not sure I get your point. What is the downside of being able to do an exportKey() on a derived key (that is derived using the deriveKey() function) in addition to being able to achieve more or less the same with deriveBits()?

Also, is there any reason to want to derive the KDF key using deriveKey() when deriveKey() itself needs a KDF key as its input?

@twiss
Copy link
Member

twiss commented Mar 27, 2022

@beebeetles You can use ECDH to derive a KDF key. And then, if the ECDH key is non-extractable and doesn't have deriveBits in the permitted usages, using deriveKey + exportKey to circumvent that shouldn't be possible either. Of course, if the key does have deriveBits in the permitted usages, then there's no downside to allowing deriveKey + exportKey, but no upside either, as then you can just use deriveBits.

@ghost
Copy link

ghost commented Mar 27, 2022

@twiss

You can use ECDH to derive a KDF key.

Good point.

if the ECDH key is non-extractable and doesn't have deriveBits in the permitted usages, using deriveKey + exportKey to circumvent that shouldn't be possible either.

I totally agree, but I think that is a separate issue from whether KDF keys should be allowed to be imported with extractable = true, isn't it? Also, if the deriveKey() + exportKey() circumvention is to be forbidden, shouldn't that be applied to all type of keys, instead of KDF keys only?

but no upside either, as then you can just use deriveBits

The problem is, with the current restriction that KDF keys cannot be importKey()ed with extactable = true, they cannot be exported into jwk format with the exportKey() function.

I think the sensible solution would be to:

  • (as you suggested) Forbid deriveKey() with extractable = true, if the basekey argument to the deriveKey() call doesn't have deriveBits listed in its permitted usages list;
  • Allow importKey() with extractable = true for all key types, without singling KDF keys out.

@twiss
Copy link
Member

twiss commented Mar 28, 2022

The problem is, with the current restriction that KDF keys cannot be importKey()ed with extactable = true, they cannot be exported into jwk format with the exportKey() function.

Currently, Web Crypto doesn't support importing KDF keys in JWK format either, since there isn't actually any specification for how to format those (as far as I know). So I wouldn't hold my breath for support for exporting KDF keys in that format.

If all you want to do is convert the key into base64url format in some JSON object, then it's much easier to do so yourself, in JavaScript, rather than trying to get the Web Crypto API to help you with that. See MDN on Base64, for example.

@ghost
Copy link

ghost commented Mar 30, 2022

Currently, Web Crypto doesn't support importing KDF keys in JWK format either, since there isn't actually any specification for how to format those (as far as I know). So I wouldn't hold my breath for support for exporting KDF keys in that format.

Good to know. Thanks! :)

@Kixunil
Copy link

Kixunil commented Apr 12, 2023

Frankly with these pointless restrictions the API is completely terrible. I've figured out what I needed but I recommend you take a hard look into it and improve it because it causes crazy waste of time. Or at least improve the documentation.

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

7 participants