diff options
author | Tobias Nießen <tniessen@tnie.de> | 2022-09-08 21:36:07 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-08 21:36:07 +0300 |
commit | 7f9cd60eef6fad245baed9896ec6376b693e089a (patch) | |
tree | 6892a4d4deac950e69abfbfee6dfbbf102210471 /doc/api | |
parent | 8a15f32d07c8fbb50528d37447ae296dd785f8eb (diff) |
doc: emphasize that createCipher is never secure
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: https://github.com/nodejs/node/pull/13821
Refs: https://github.com/nodejs/node/pull/19343
Refs: https://github.com/nodejs/node/pull/22089
PR-URL: https://github.com/nodejs/node/pull/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>
Diffstat (limited to 'doc/api')
-rw-r--r-- | doc/api/crypto.md | 8 | ||||
-rw-r--r-- | doc/api/deprecations.md | 4 |
2 files changed, 10 insertions, 2 deletions
diff --git a/doc/api/crypto.md b/doc/api/crypto.md index dc581cbd82b..66fb2f207bd 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -3013,6 +3013,10 @@ The `password` is used to derive the cipher key and initialization vector (IV). The value must be either a `'latin1'` encoded string, a [`Buffer`][], a `TypedArray`, or a `DataView`. +<strong class="critical">This function is semantically insecure for all +supported ciphers and fatally flawed for ciphers in counter mode (such as CTR, +GCM, or CCM).</strong> + The implementation of `crypto.createCipher()` derives keys using the OpenSSL function [`EVP_BytesToKey`][] with the digest algorithm set to MD5, one iteration, and no salt. The lack of salt allows dictionary attacks as the same @@ -3136,6 +3140,10 @@ cipher in CCM or OCB mode (e.g. `'aes-128-ccm'`) is used. In that case, the authentication tag in bytes, see [CCM mode][]. For `chacha20-poly1305`, the `authTagLength` option defaults to 16 bytes. +<strong class="critical">This function is semantically insecure for all +supported ciphers and fatally flawed for ciphers in counter mode (such as CTR, +GCM, or CCM).</strong> + The implementation of `crypto.createDecipher()` derives keys using the OpenSSL function [`EVP_BytesToKey`][] with the digest algorithm set to MD5, one iteration, and no salt. The lack of salt allows dictionary attacks as the same diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 7cfe0c01ee0..d3f3eac9cef 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -2114,10 +2114,10 @@ changes: Type: Runtime -Using [`crypto.createCipher()`][] and [`crypto.createDecipher()`][] should be +Using [`crypto.createCipher()`][] and [`crypto.createDecipher()`][] must be avoided as they use a weak key derivation function (MD5 with no salt) and static initialization vectors. It is recommended to derive a key using -[`crypto.pbkdf2()`][] or [`crypto.scrypt()`][] and to use +[`crypto.pbkdf2()`][] or [`crypto.scrypt()`][] with random salts and to use [`crypto.createCipheriv()`][] and [`crypto.createDecipheriv()`][] to obtain the [`Cipher`][] and [`Decipher`][] objects respectively. |