@@ -537,6 +537,9 @@ of the ciphertext in bytes. See [CCM mode][]. |
537 | 537 |
|
538 | 538 | The `decipher.setAAD()` method must be called before [`decipher.update()`][]. |
539 | 539 |
|
| 540 | +When passing a string as the `buffer`, please consider |
| 541 | +[caveats when using strings as inputs to cryptographic APIs][]. |
| 542 | + |
540 | 543 | ### `decipher.setAuthTag(buffer[, encoding])` |
541 | 544 | <!-- YAML |
542 | 545 | added: v1.0.0 |
@@ -569,6 +572,9 @@ The `decipher.setAuthTag()` method must be called before [`decipher.update()`][] |
569 | 572 | for `CCM` mode or before [`decipher.final()`][] for `GCM` and `OCB` modes. |
570 | 573 | `decipher.setAuthTag()` can only be called once. |
571 | 574 |
|
| 575 | +When passing a string as the authentication tag, please consider |
| 576 | +[caveats when using strings as inputs to cryptographic APIs][]. |
| 577 | + |
572 | 578 | ### `decipher.setAutoPadding([autoPadding])` |
573 | 579 | <!-- YAML |
574 | 580 | added: v0.7.1 |
@@ -2161,6 +2167,9 @@ The `key` is the raw key used by the `algorithm` and `iv` is an |
2161 | 2167 | a [`KeyObject`][] of type `secret`. If the cipher does not need |
2162 | 2168 | an initialization vector, `iv` may be `null`. |
2163 | 2169 |
|
| 2170 | +When passing strings for `key` or `iv`, please consider |
| 2171 | +[caveats when using strings as inputs to cryptographic APIs][]. |
| 2172 | + |
2164 | 2173 | Initialization vectors should be unpredictable and unique; ideally, they will be |
2165 | 2174 | cryptographically random. They do not have to be secret: IVs are typically just |
2166 | 2175 | added to ciphertext messages unencrypted. It may sound contradictory that |
@@ -2257,6 +2266,9 @@ The `key` is the raw key used by the `algorithm` and `iv` is an |
2257 | 2266 | a [`KeyObject`][] of type `secret`. If the cipher does not need |
2258 | 2267 | an initialization vector, `iv` may be `null`. |
2259 | 2268 |
|
| 2269 | +When passing strings for `key` or `iv`, please consider |
| 2270 | +[caveats when using strings as inputs to cryptographic APIs][]. |
| 2271 | + |
2260 | 2272 | Initialization vectors should be unpredictable and unique; ideally, they will be |
2261 | 2273 | cryptographically random. They do not have to be secret: IVs are typically just |
2262 | 2274 | added to ciphertext messages unencrypted. It may sound contradictory that |
@@ -3097,6 +3109,9 @@ but will take a longer amount of time to complete. |
3097 | 3109 | The `salt` should be as unique as possible. It is recommended that a salt is |
3098 | 3110 | random and at least 16 bytes long. See [NIST SP 800-132][] for details. |
3099 | 3111 |
|
| 3112 | +When passing strings for `password` or `salt`, please consider |
| 3113 | +[caveats when using strings as inputs to cryptographic APIs][]. |
| 3114 | + |
3100 | 3115 | ```js |
3101 | 3116 | const crypto = require('crypto'); |
3102 | 3117 | crypto.pbkdf2('secret', 'salt', 100000, 64, 'sha512', (err, derivedKey) => { |
@@ -3168,6 +3183,9 @@ but will take a longer amount of time to complete. |
3168 | 3183 | The `salt` should be as unique as possible. It is recommended that a salt is |
3169 | 3184 | random and at least 16 bytes long. See [NIST SP 800-132][] for details. |
3170 | 3185 |
|
| 3186 | +When passing strings for `password` or `salt`, please consider |
| 3187 | +[caveats when using strings as inputs to cryptographic APIs][]. |
| 3188 | + |
3171 | 3189 | ```js |
3172 | 3190 | const crypto = require('crypto'); |
3173 | 3191 | const key = crypto.pbkdf2Sync('secret', 'salt', 100000, 64, 'sha512'); |
@@ -3656,6 +3674,9 @@ memory-wise in order to make brute-force attacks unrewarding. |
3656 | 3674 | The `salt` should be as unique as possible. It is recommended that a salt is |
3657 | 3675 | random and at least 16 bytes long. See [NIST SP 800-132][] for details. |
3658 | 3676 |
|
| 3677 | +When passing strings for `password` or `salt`, please consider |
| 3678 | +[caveats when using strings as inputs to cryptographic APIs][]. |
| 3679 | + |
3659 | 3680 | The `callback` function is called with two arguments: `err` and `derivedKey`. |
3660 | 3681 | `err` is an exception object when key derivation fails, otherwise `err` is |
3661 | 3682 | `null`. `derivedKey` is passed to the callback as a [`Buffer`][]. |
@@ -3714,6 +3735,9 @@ memory-wise in order to make brute-force attacks unrewarding. |
3714 | 3735 | The `salt` should be as unique as possible. It is recommended that a salt is |
3715 | 3736 | random and at least 16 bytes long. See [NIST SP 800-132][] for details. |
3716 | 3737 |
|
| 3738 | +When passing strings for `password` or `salt`, please consider |
| 3739 | +[caveats when using strings as inputs to cryptographic APIs][]. |
| 3740 | + |
3717 | 3741 | An exception is thrown when key derivation fails, otherwise the derived key is |
3718 | 3742 | returned as a [`Buffer`][]. |
3719 | 3743 |
|
@@ -3923,6 +3947,47 @@ See the [Web Crypto API documentation][] for details. |
3923 | 3947 |
|
3924 | 3948 | ## Notes |
3925 | 3949 |
|
| 3950 | +### Using strings as inputs to cryptographic APIs |
| 3951 | + |
| 3952 | +For historical reasons, many cryptographic APIs provided by Node.js accept |
| 3953 | +strings as inputs where the underlying cryptographic algorithm works on byte |
| 3954 | +sequences. These instances include plaintexts, ciphertexts, symmetric keys, |
| 3955 | +initialization vectors, passphrases, salts, authentication tags, |
| 3956 | +and additional authenticated data. |
| 3957 | + |
| 3958 | +When passing strings to cryptographic APIs, consider the following factors. |
| 3959 | + |
| 3960 | +* Not all byte sequences are valid UTF-8 strings. Therefore, when a byte |
| 3961 | + sequence of length `n` is derived from a string, its entropy is generally |
| 3962 | + lower than the entropy of a random or pseudo-random `n` byte sequence. |
| 3963 | + For example, no UTF-8 string will result in the byte sequence `c0 af`. Secret |
| 3964 | + keys should almost exclusively be random or pseudo-random byte sequences. |
| 3965 | +* Similarly, when converting random or pseudo-random byte sequences to UTF-8 |
| 3966 | + strings, subsequences that do not represent valid code points may be replaced |
| 3967 | + by the Unicode replacement character (`U+FFFD`). The byte representation of |
| 3968 | + the resulting Unicode string may, therefore, not be equal to the byte sequence |
| 3969 | + that the string was created from. |
| 3970 | + |
| 3971 | + ```js |
| 3972 | + const original = [0xc0, 0xaf]; |
| 3973 | + const bytesAsString = Buffer.from(original).toString('utf8'); |
| 3974 | + const stringAsBytes = Buffer.from(bytesAsString, 'utf8'); |
| 3975 | + console.log(stringAsBytes); |
| 3976 | + // Prints '<Buffer ef bf bd ef bf bd>'. |
| 3977 | + ``` |
| 3978 | + |
| 3979 | + The outputs of ciphers, hash functions, signature algorithms, and key |
| 3980 | + derivation functions are pseudo-random byte sequences and should not be |
| 3981 | + used as Unicode strings. |
| 3982 | +* When strings are obtained from user input, some Unicode characters can be |
| 3983 | + represented in multiple equivalent ways that result in different byte |
| 3984 | + sequences. For example, when passing a user passphrase to a key derivation |
| 3985 | + function, such as PBKDF2 or scrypt, the result of the key derivation function |
| 3986 | + depends on whether the string uses composed or decomposed characters. Node.js |
| 3987 | + does not normalize character representations. Developers should consider using |
| 3988 | + [`String.prototype.normalize()`][] on user inputs before passing them to |
| 3989 | + cryptographic APIs. |
| 3990 | + |
3926 | 3991 | ### Legacy streams API (prior to Node.js 0.10) |
3927 | 3992 |
|
3928 | 3993 | The Crypto module was added to Node.js before there was the concept of a |
@@ -4384,6 +4449,7 @@ See the [list of SSL OP Flags][] for details. |
4384 | 4449 | [AEAD algorithms]: https://en.wikipedia.org/wiki/Authenticated_encryption |
4385 | 4450 | [CCM mode]: #crypto_ccm_mode |
4386 | 4451 | [Caveats]: #crypto_support_for_weak_or_compromised_algorithms |
| 4452 | +[caveats when using strings as inputs to cryptographic APIs]: #crypto_using_strings_as_inputs_to_cryptographic_apis |
4387 | 4453 | [Crypto constants]: #crypto_crypto_constants_1 |
4388 | 4454 | [HTML 5.2]: https://www.w3.org/TR/html52/changes.html#features-removed |
4389 | 4455 | [HTML5's `keygen` element]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/keygen |
@@ -4406,6 +4472,7 @@ See the [list of SSL OP Flags][] for details. |
4406 | 4472 | [`EVP_BytesToKey`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_BytesToKey.html |
4407 | 4473 | [`KeyObject`]: #crypto_class_keyobject |
4408 | 4474 | [`Sign`]: #crypto_class_sign |
| 4475 | +[`String.prototype.normalize()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize |
4409 | 4476 | [`UV_THREADPOOL_SIZE`]: cli.md#cli_uv_threadpool_size_size |
4410 | 4477 | [`Verify`]: #crypto_class_verify |
4411 | 4478 | [`cipher.final()`]: #crypto_cipher_final_outputencoding |
|