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

crypto: warn if counter mode used in createCipher #13821

Closed
wants to merge 2 commits into from

Conversation

shigeki
Copy link
Contributor

@shigeki shigeki commented Jun 20, 2017

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.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

crypto

Fixes: #13801

CC @bnoordhuis, @indutny

@shigeki shigeki added crypto Issues and PRs related to the crypto subsystem. semver-major PRs that contain breaking changes and should be released in the next major version. labels Jun 20, 2017
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. labels Jun 20, 2017
@shigeki
Copy link
Contributor Author

shigeki commented Jun 20, 2017

@iangcarroll
Copy link

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:

When using ciphers that require an initialization vector, createCipher will insecurely derive a non-random initialization vector from the key you provide. Messages with the same plaintext will always have the same ciphertext. Never use createCipher with counter modes (e.g. CTR, GCM or CCM), as reusing initialization vectors may result in no encryption at all. A warning will be emitted if you attempt to use createCipher with one of these modes.

Though if it goes in an alert box it'll obviously need to be more concise. Maybe just "Don't use this function".

@tniessen
Copy link
Member

Maybe just "Don't use this function".

See #13801 (comment), there are justified use cases of createCipher.

@tniessen
Copy link
Member

I think the problems and security implications of using createCipher are not limited to counter modes, but FWIW, this won't make it worse.

@iangcarroll
Copy link

there are justified use cases of createCipher.

"Don't use it" was mostly a joke, but still holds true even for ECB. ;)

but FWIW, this won't make it worse.

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".

Copy link
Member

@indutny indutny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM


int mode = EVP_CIPHER_CTX_mode(&ctx_);
if (encrypt && (mode == EVP_CIPH_CTR_MODE || mode == EVP_CIPH_GCM_MODE ||
mode == EVP_CIPH_CCM_MODE))
Copy link
Member

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 {...}?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Fixed.

@cbarcenas
Copy link

cbarcenas commented Jun 20, 2017

Thanks for getting the ball rolling on a fix for this, @shigeki! Some thoughts:

crypto.createCipher() sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used.

"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 createCipher to fail when called with a block mode that requires an IV. Yes, this is a API-breaking change, but it's much better than the current behavior. The current behavior is completely broken in a cryptographic sense once the same password is used for more than one encryption operation!

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. generateLegacyKey/generateLegacyIV), so existing projects that rely on the old behavior of createCipher could easily generate the same key/IV data from their preexisting passwords. Because such an API call would be deprecated, it would serve as good impetus to migrate behavior away from the broken key/IV-generation scheme and move toward proper use of these block cipher modes via createCipheriv.

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.

@bnoordhuis
Copy link
Member

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?

@stouset
Copy link

stouset commented Jun 20, 2017

@cbarcenas That is an improvement over the current situation, but a better approach in my opinion is for crypto.createCipher to generate IVs for the end-user, and return them with the output of cipher.final(). Or alternatively, if you don't want to change semantics of existing functions, deprecate the existing function and replace it with a newly-named one.

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 crypto.createCipher would also eliminate this entire class of weakness.

If a user does want to take things into their own hands, they can use the existing createCipheriv.

@cbarcenas
Copy link

cbarcenas commented Jun 20, 2017

@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 cipher.final() will break decryption in projects that take ciphertext output from cipher.final() and blindly pass it into decipher.update() without preprocessing.

I guess an underlying question here is whether the crypto module is intended to provide high- or low-level cryptographic functionality.

@mscdex
Copy link
Contributor

mscdex commented Jun 20, 2017

Also, I think having differing .final() return values depending on whether createCipher() or createCipheriv() was used would be unexpected behavior. On top of that, returning objects (plain or otherwise) from C++ land would decrease performance (although passing an object created in JS land to C++ land might be slightly faster -- at least it used to be).

@stouset
Copy link

stouset commented Jun 21, 2017

@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.

@shigeki
Copy link
Contributor Author

shigeki commented Jun 21, 2017

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 crypto.createCipher if it is used only once or keys are changed in every encryptions.
For example in case of plain text is known, we can do it unless it has hash collision as

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 crypto.createCipheriv. Some people might use a random value as nonce such that

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.
That is why AES-SIV RFC5297) and AES-GCM-SIV are developed. We should encourage to use them against nonce reuse. Unfortunately, they are not yet widely used. AES-GCM-SIV is under standardization and only boringSSL has just supported it recently. I think we can only let users generate IV to meet their use and security requirements for now.

Copy link
Member

@bnoordhuis bnoordhuis left a 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.

@@ -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.
Copy link
Member

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...)

Copy link
Contributor Author

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.

Copy link

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.

Copy link
Member

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:

https://stackoverflow.com/questions/3141860/aes-ctr-256-encryption-mode-of-operation-on-openssl/3146214#3146214

Copy link

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.

Copy link
Contributor Author

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.

Copy link
Member

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.

Copy link

@stouset stouset Aug 22, 2017

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.

Copy link
Member

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.
@shigeki
Copy link
Contributor Author

shigeki commented Aug 21, 2017

Rebased against the latest master and CI is running on https://ci.nodejs.org/job/node-test-pull-request/9777/.

Copy link
Member

@bnoordhuis bnoordhuis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still LGTM.

@shigeki
Copy link
Contributor Author

shigeki commented Aug 22, 2017

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.

@shigeki shigeki closed this Aug 22, 2017
MylesBorins pushed a commit that referenced this pull request Sep 12, 2017
`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>
@MylesBorins
Copy link
Member

Should this be backported to v6.x-staging? If yes please follow the guide and raise a backport PR, if no let me know or add the dont-land-on label.

bnoordhuis pushed a commit to bnoordhuis/io.js that referenced this pull request Oct 29, 2017
`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>
bnoordhuis added a commit to bnoordhuis/io.js that referenced this pull request Oct 29, 2017
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
@bnoordhuis
Copy link
Member

v6.x: #16583

MylesBorins pushed a commit that referenced this pull request Nov 14, 2017
`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>
@MylesBorins MylesBorins mentioned this pull request Nov 21, 2017
MylesBorins pushed a commit that referenced this pull request Nov 21, 2017
`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>
MylesBorins pushed a commit that referenced this pull request Nov 28, 2017
`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>
@ChALkeR ChALkeR added the security Issues and PRs related to security. label Jan 27, 2018
tniessen added a commit to tniessen/node that referenced this pull request Sep 6, 2022
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
nodejs-github-bot pushed a commit that referenced this pull request Sep 8, 2022
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>
Fyko pushed a commit to Fyko/node that referenced this pull request Sep 15, 2022
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>
RafaelGSS pushed a commit that referenced this pull request Sep 26, 2022
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>
RafaelGSS pushed a commit that referenced this pull request Sep 26, 2022
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>
RafaelGSS pushed a commit that referenced this pull request Sep 26, 2022
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>
juanarbol pushed a commit that referenced this pull request Oct 4, 2022
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>
juanarbol pushed a commit that referenced this pull request Oct 4, 2022
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>
juanarbol pushed a commit that referenced this pull request Oct 4, 2022
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>
juanarbol pushed a commit that referenced this pull request Oct 7, 2022
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>
juanarbol pushed a commit that referenced this pull request Oct 10, 2022
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>
juanarbol pushed a commit that referenced this pull request Oct 11, 2022
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>
guangwong pushed a commit to noslate-project/node that referenced this pull request Jan 3, 2023
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>
guangwong pushed a commit to noslate-project/node that referenced this pull request Jan 3, 2023
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. security Issues and PRs related to security.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

crypto.createCipher should not work with AES-CTR