Customize password-based KDF in `KeyObject#export`
What is the problem this feature will solve?
At the moment, node.js uses OpenSSL defaults when exporting a key object
const { privateKey } = generateKeyPairSync("ec", {
namedCurve: "P-384",
privateKeyEncoding: {
type: "pkcs8",
format: "pem",
cipher: "aes-256-cbc",
passphrase: "something secret",
},
});
generates a PEM-encoded encrypted private key with 2048 iterations of PBKDF2-HMAC-SHA256. OWASP recommends way more (600k).
What is the feature you are proposing to solve the problem?
In OpenSSL CLI openssl pkcs8 -topk8, the iterations are customizable with the -iter option.
Alternatively, one can choose -scrypt (and relevant -scrypt_N/r/p params) as the KDF in OpenSSL but not in node.js.
The PRF can also be a different HMAC-SHAxxx but that's less relevant in my opinion
I open the discussion for extending KeyObject#export and related interfaces with one of the following
- A
derivedKeyparameter that excludespassphrase. In this case, no KDF is performed, and it is strongly emphasised to pass a key derived withscrypt,pbkdf2, orargon2id(node.js support one day :crossed_fingers:) (EDIT: support for argon2id introduced in OpenSSL 3.2.0)
privateKeyEncoding: {
...
cipher: "aes-256-cbc",
derivedKey: await promisifiedScrypt(weakUserPassphrase, salt, 32, { p: 5 }) // {@link <https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#scrypt>}
}
- Extend
cipherto be an object
cipher: {
alg: "aes-256-cbc",
kdf: "pbkdf2",
iter: 600_000,
/* prf: "hmacWithSHA256" */
// mutually exclusive
alg: "aes-256-cbc",
kdf: "scrypt",
cost: ...,
// same options as with crypto.scrypt
}
- Change the default iterations count to follow OWASP guidelines. This loses parity with OpenSSL defaults, which can be confusing for users, and there is no extensibility in case OWASP removes pbkdf2 from its recommandation. I am strongly against it, but its implementation would seem the less painful of all
What alternatives have you considered?
Install OpenSSL on operating systems that don't provide it (hello Windows) and encrypt with its CLI (via child_process or a terminal)
There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the https://github.com/nodejs/node/labels/never-stale label or close this issue if it should be closed. If not, the issue will be automatically closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document.
Can we consider putting the never-stale label on this issue, or try to solve it?
There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the https://github.com/nodejs/node/labels/never-stale label or close this issue if it should be closed. If not, the issue will be automatically closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document.
There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment.
For more information on how the project manages feature requests, please consult the feature request management document.
I don't consider this an unreasonable request. Any chance there will be a never-stale tag to it?