-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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
crypto: warn if counter mode used in createCipher #13821
Conversation
CI is running on https://ci.nodejs.org/job/node-test-pull-request/8760/. |
Is it possible to put the documentation warning in a box like one of the alerts for stability notices? This really needs to be more prominent, and the wording should be more direct, i.e replace the entire paragraph with something like:
Though if it goes in an alert box it'll obviously need to be more concise. Maybe just "Don't use this function". |
See #13801 (comment), there are justified use cases of |
I think the problems and security implications of using |
"Don't use it" was mostly a joke, but still holds true even for ECB. ;)
Well, I mean, sure. I'd still say the documentation needs to be stronger here before it's merged. Especially if people come across the warning and the documentation says it's a "recommendation". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
src/node_crypto.cc
Outdated
|
||
int mode = EVP_CIPHER_CTX_mode(&ctx_); | ||
if (encrypt && (mode == EVP_CIPH_CTR_MODE || mode == EVP_CIPH_GCM_MODE || | ||
mode == EVP_CIPH_CCM_MODE)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicking: could you please surround if
's body with braces {...}
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Fixed.
Thanks for getting the ball rolling on a fix for this, @shigeki! Some thoughts:
"Leads to a security risk" is a huge understatement... in common block cipher modes (e.g. CTR), IV reuse is catastrophic to confidentiality. Observing just a few ciphertexts is sufficient in many cases to derive the underlying key and/or plaintexts, compromising the encryption scheme entirely. (See here for a good explanation.) Reiterating my concerns from #13801, I think a much better change is for If Node were to adopt this fail-fast behavior, the legacy key/IV generation should be exposed in a public immediately-deprecated API (e.g. What are your thoughts about this? I must admit, I have never contributed to this project before, so I'm not sure of the feasibility of these changes and I may not have the sufficient context on this project to make the changes myself, but I'm happy to hear what veterans of this project might think about this proposal. |
I think I'm +1 on @cbarcenas's proposal. It's been proven time and time again that users simply ignore or mute warnings so I don't have much hope for this PR. If we're going to make a hard break, are there other things that should go? |
@cbarcenas That is an improvement over the current situation, but a better approach in my opinion is for Users should not, in the general case, be asked to deal with details like IV generation. Modes like CTR have different security requirements (uniqueness) than CBC (unpredictability), and users will not consistently get this right. Similarly, modes like GCM only provide an advantage when the auth tag is actually provided during decryption. Naïve searching shows that only about 80% of users actually take this step when using GCM. Including the auth tag (when relevant) in the output when using If a user does want to take things into their own hands, they can use the existing |
@stouset I agree with you in principle that letting Node handle IV generation would improve usability and security. However, something to consider here is making these changes as backwards-compatible as possible, and giving projects an easy path to remediate this issue without relying these projects' developers to have cryptographic expertise. My main concern is that including the IV in the output of I guess an underlying question here is whether the |
Also, I think having differing |
@cbarcenas Yeah, I wouldn't mind such an API having a new name. @mscdex The return value wouldn't change. It would just be slightly longer to accommodate the IV (and ideally tag, for authenticated encryption). This would be essentially transparent to consumers of the API. |
I agree that nonce reuse in counter mode leads catastrophic. For examples in TLS case of AES-GCM, "Nonce-Disrespecting Adversaries" shows that the MAC key of GHASH can be derived and encrypted message can be tampered by bit flipping. I wrote a modest description in the doc because the nonce is not always reused in const crypto = require('crypto');
const key = 'pass';
const plain = 'hello world';
const cipher = crypto.createCipher('aes-128-gcm', crypto.createHmac('sha256', key).update(plain).digest());
const encrypted = cipher.update(plain); I also think that we cannot prohibit reused nonce even if we use const crypto = require('crypto');
const key = 'pass';
const plain = 'hello world';
const cipher = crypto.createCipheriv('aes-128-gcm', key, crypto.randomBytes(12));
const encrypted = cipher.update(plain); But it has a possibility of nonce reused when it is called in extremely large number due to birthday paradox. The situation of nonce reused largely depends on how user use it and I think we cannot cover all the cases. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a rebase but let's land it, it still improves on the status quo.
doc/api/crypto.md
Outdated
@@ -1196,7 +1196,8 @@ rapidly. | |||
In line with OpenSSL's recommendation to use pbkdf2 instead of | |||
[`EVP_BytesToKey`][] it is recommended that developers derive a key and IV on | |||
their own using [`crypto.pbkdf2()`][] and to use [`crypto.createCipheriv()`][] | |||
to create the `Cipher` object. | |||
to create the `Cipher` object. A warning is emitted when counter mode (e.g. CTR, | |||
GCM or CCM) is used in `crypto.createCipher()` in order to avoid IV reuse. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe make this warning a little stronger, e.g. "a predictable IV undermines the security of counter-based ciphers."
Would it be worthwhile to mention that this API predates the addition of counter-based ciphers to OpenSSL, hence why it's not an error outright?
(Really, the more I think about it, the more I feel throwing an exception is the right thing to do. If it weren't for backwards compatibility...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the doc into a little stronger description as ae7dbb1 and add a reference of Nonce-Disrespecting Adversaries.
Would it be worthwhile to mention that this API predates the addition of counter-based ciphers to OpenSSL, hence why it's not an error outright?
I think it gets more complicated description in the doc. We can make throwing an error some time later after enough time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A predictable IV does not undermine the security of counter-based ciphers. In fact, a simple incrementing counter is a recommended approach when using counter-based schemes that have IVs too small to reliably be generated uniquely at random.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stouset I think you may be misunderstanding how openssl implements them and what "IV" means in that context. The best description I could find:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked the link, and I might be wrong but I don't think anything in it contradicts my response. I'll do some more research, but at the very least the wording you suggested may be confusing and need clarification if there's a particular reason it's accurate in this case. I'm in an area with poor signal but I should be able to take a better look later tonight.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that IV should be a nonce not a random so that it must not be reused with the same secret key but it can be predictable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I think the confusion is around the fact that the IV to OpenSSL's EVP_CipherInit_ex()
is the concatenation of the nonce and the counter as a single bit string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, but it's fine if that's predictable as long as it's never repeated. The nonce in CTR mode can be predictable (and is often recommended to be a simple counter in appropriate contexts), and the counter is itself just an actual counter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we are in disagreement. Is your beef with the wording in this PR? Can you suggest an alternative?
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse.
Rebased against the latest master and CI is running on https://ci.nodejs.org/job/node-test-pull-request/9777/. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still LGTM.
The previous CI had an Jenkins error. A new CI of https://ci.nodejs.org/job/node-test-commit/11951/ is all green. Landed in 9dfb2d1. @stouset If you have any proposal, please submit a new PR. Thanks for reviewers. |
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Fixes: #13801 PR-URL: #13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Should this be backported to |
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Fixes: nodejs#13801 PR-URL: nodejs#13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
The previous commit is a back-port of pull request nodejs#13821 to v6.x. Its regression test does not apply to the v6.x branch (depends on semver-major pull request nodejs#9405) so this commit adds a new test. Refs: nodejs#13821 Refs: nodejs#9405
v6.x: #16583 |
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Backport-PR-URL: #16583 Fixes: #13801 PR-URL: #13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Backport-PR-URL: #16583 Fixes: #13801 PR-URL: #13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
`crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Backport-PR-URL: #16583 Fixes: #13801 PR-URL: #13821 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: nodejs#13821 Refs: nodejs#19343 Refs: nodejs#22089
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: #13821 Refs: #19343 Refs: #22089 PR-URL: #44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: nodejs#13821 Refs: nodejs#19343 Refs: nodejs#22089 PR-URL: nodejs#44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: #13821 Refs: #19343 Refs: #22089 PR-URL: #44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: #13821 Refs: #19343 Refs: #22089 PR-URL: #44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: #13821 Refs: #19343 Refs: #22089 PR-URL: #44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: #13821 Refs: #19343 Refs: #22089 PR-URL: #44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: #13821 Refs: #19343 Refs: #22089 PR-URL: #44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: #13821 Refs: #19343 Refs: #22089 PR-URL: #44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: #13821 Refs: #19343 Refs: #22089 PR-URL: #44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: #13821 Refs: #19343 Refs: #22089 PR-URL: #44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: #13821 Refs: #19343 Refs: #22089 PR-URL: #44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: nodejs/node#13821 Refs: nodejs/node#19343 Refs: nodejs/node#22089 PR-URL: nodejs/node#44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
The current documentation clearly states that createCipher() and createDecipher() should not be used with ciphers in counter mode, but (1) this is an understatement, and (2) these functions are (semantically) insecure for ciphers in any other supported block cipher mode as well. Semantic security requires IND-CPA, but a deterministic cipher with fixed key and IV, such as those generated by these functions, does not fulfill IND-CPA. Are there justified use cases for createCipher() and createDecipher()? Yes and no. The only case in which these functions can be used in a semantically secure manner arises only when the password argument is not actually a password but rather a random or pseudo-random sequence that is unpredictable and that is never reused (e.g., securely derived from a password with a proper salt). Insofar, it is possible to use these APIs without immediately creating a vulnerability. However, - any application that manages to fulfill this requirement should also be able to fulfill the similar requirements of crypto.createCipheriv() and those of crypto.createDecipheriv(), which give much more control over key and initialization vector, and - the MD5-based key derivation step generally does not help and might even reduce the overall security due to its many weaknesses. Refs: nodejs/node#13821 Refs: nodejs/node#19343 Refs: nodejs/node#22089 PR-URL: nodejs/node#44538 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
crypto.createCipher()
sets the fixed IV derived from password and itleads to a security risk of nonce reuse when counter mode is used.
A warning is emitted when CTR, GCM or CCM is used in
crypto.createCipher()
to notify users to avoid nonce reuse.Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
crypto
Fixes: #13801
CC @bnoordhuis, @indutny