Repository navigation
hkdf API is inconsistent with other supported KDFs #39471
Description
Activity
- addedcryptoIssues and PRs related to the crypto subsystem.Issues and PRs related to the crypto subsystem.securityIssues and PRs related to security.Issues and PRs related to security.
on Jul 20, 2021 The only non-breaking way out of it I see is
- deprecate now and later remove
hkdf - expose 'crypto/kdf' module => { hkdf, scrypt, pbkdf2 } with scrypt and pbhkf2 being aliases? while hkdf having Buffer as a return type and well-ordered arguments
KDFs would having their own module is then the remaining inconsistency with the rest of the
cryptomodule?- deprecate now and later remove
I disagree with it being an actual issue but, I won't block if someone wants to change things so long as hkdf is not removed.
That said, there's no reason to expose a different module or make any breaking changes to the existing APIs. We can simply expose a single
crypto.kdf(options)function...const pbkdf2 = crypto.kdfSync({ type: 'pbkdf2', password, salt, iterations, keyLength, digest, arrayBuffer: [true|false], }); const scrypt = crypto.kdfSync({ type: 'scrypt', password, salt, keyLength, arrayBuffer: [true|false], }); const hkdf = crypto.kdfSync({ type: 'hkdf', digest, password, salt, info, keyLength, arrayBuffer: [true|false], );
I don't have a strong opinion. I do believe that the current API is not ideal and should have aimed for consistency with Node.js and not with WebCrypto, but I don't see a way to solve that problem now without breaking existing code. Adding more APIs makes things more complicated and does not actually solve the problem at hand. I opened this issue mostly so that, when someone does come across this problem, they will find a resolution, even if that resolution is
wontfix.Adding more APIs makes things more complicated and does not actually solve the problem at hand.
Why does replacing the current API not solve the problem at hand?
- added a commit that references this issue
on Jul 26, 2021 - added a commit that references this issue
on Aug 2, 2021 I still think it's not ideal that we are being inconsistent in when we return
Buffer,ArrayBuffer, orUint8Array, but I don't see this improving, so I am closing the issue.
Node.js supports three KDFs:
Output:
Inconsistencies:
ArrayBuffer, not a Node.jsBuffer. In the async case, the callback even has the same signature and same argument names(err, derivedKey), but they derived key is not aBufferwhen using HKDF.pbkdf2.And this can absolutely lead to security issues. The output is computationally indistinguishable from a random bit sequence and all three KDFs are collision-resistant and preimage-resistant, therefore, the comparison of outputs does not necessarily need to be timing-safe. While not advisable, it is possible (depending on the application) to compare the outputs in a timing-unsafe manner without compromising the password
to compare the output of the KDF to a known correct value, e.g., as part of a login procedure. Now change
aandbtoArrayBuffereach, and suddenly, the condition is always true, sinceWhen scrypt was added, we had a lengthy discussion about designing KDF APIs. Quoting #21766 (comment):
Is there anything we can do about it now? Or simply label it
wontfixand close the issue?Refs: #21766
Refs: #35093
Refs: #39453