@@ -537,6 +537,9 @@ of the ciphertext in bytes. See [CCM mode][].
537537
538538The ` decipher.setAAD() ` method must be called before [ ` decipher.update() ` ] [ ] .
539539
540+ When passing a string as the ` buffer ` , please consider
541+ [ caveats when using strings as inputs to cryptographic APIs] [ ] .
542+
540543### ` decipher.setAuthTag(buffer[, encoding]) `
541544<!-- YAML
542545added: v1.0.0
@@ -569,6 +572,9 @@ The `decipher.setAuthTag()` method must be called before [`decipher.update()`][]
569572for ` CCM ` mode or before [ ` decipher.final() ` ] [ ] for ` GCM ` and ` OCB ` modes.
570573` decipher.setAuthTag() ` can only be called once.
571574
575+ When passing a string as the authentication tag, please consider
576+ [ caveats when using strings as inputs to cryptographic APIs] [ ] .
577+
572578### ` decipher.setAutoPadding([autoPadding]) `
573579<!-- YAML
574580added: v0.7.1
@@ -2161,6 +2167,9 @@ The `key` is the raw key used by the `algorithm` and `iv` is an
21612167a [ ` KeyObject ` ] [ ] of type ` secret ` . If the cipher does not need
21622168an initialization vector, ` iv ` may be ` null ` .
21632169
2170+ When passing strings for ` key ` or ` iv ` , please consider
2171+ [ caveats when using strings as inputs to cryptographic APIs] [ ] .
2172+
21642173Initialization vectors should be unpredictable and unique; ideally, they will be
21652174cryptographically random. They do not have to be secret: IVs are typically just
21662175added 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
22572266a [ ` KeyObject ` ] [ ] of type ` secret ` . If the cipher does not need
22582267an initialization vector, ` iv ` may be ` null ` .
22592268
2269+ When passing strings for ` key ` or ` iv ` , please consider
2270+ [ caveats when using strings as inputs to cryptographic APIs] [ ] .
2271+
22602272Initialization vectors should be unpredictable and unique; ideally, they will be
22612273cryptographically random. They do not have to be secret: IVs are typically just
22622274added to ciphertext messages unencrypted. It may sound contradictory that
@@ -3097,6 +3109,9 @@ but will take a longer amount of time to complete.
30973109The ` salt ` should be as unique as possible. It is recommended that a salt is
30983110random and at least 16 bytes long. See [ NIST SP 800-132] [ ] for details.
30993111
3112+ When passing strings for ` password ` or ` salt ` , please consider
3113+ [ caveats when using strings as inputs to cryptographic APIs] [ ] .
3114+
31003115``` js
31013116const crypto = require (' crypto' );
31023117crypto .pbkdf2 (' secret' , ' salt' , 100000 , 64 , ' sha512' , (err , derivedKey ) => {
@@ -3168,6 +3183,9 @@ but will take a longer amount of time to complete.
31683183The ` salt ` should be as unique as possible. It is recommended that a salt is
31693184random and at least 16 bytes long. See [ NIST SP 800-132] [ ] for details.
31703185
3186+ When passing strings for ` password ` or ` salt ` , please consider
3187+ [ caveats when using strings as inputs to cryptographic APIs] [ ] .
3188+
31713189``` js
31723190const crypto = require (' crypto' );
31733191const key = crypto .pbkdf2Sync (' secret' , ' salt' , 100000 , 64 , ' sha512' );
@@ -3656,6 +3674,9 @@ memory-wise in order to make brute-force attacks unrewarding.
36563674The ` salt ` should be as unique as possible. It is recommended that a salt is
36573675random and at least 16 bytes long. See [ NIST SP 800-132] [ ] for details.
36583676
3677+ When passing strings for ` password ` or ` salt ` , please consider
3678+ [ caveats when using strings as inputs to cryptographic APIs] [ ] .
3679+
36593680The ` callback ` function is called with two arguments: ` err ` and ` derivedKey ` .
36603681` err ` is an exception object when key derivation fails, otherwise ` err ` is
36613682` null ` . ` derivedKey ` is passed to the callback as a [ ` Buffer ` ] [ ] .
@@ -3714,6 +3735,9 @@ memory-wise in order to make brute-force attacks unrewarding.
37143735The ` salt ` should be as unique as possible. It is recommended that a salt is
37153736random and at least 16 bytes long. See [ NIST SP 800-132] [ ] for details.
37163737
3738+ When passing strings for ` password ` or ` salt ` , please consider
3739+ [ caveats when using strings as inputs to cryptographic APIs] [ ] .
3740+
37173741An exception is thrown when key derivation fails, otherwise the derived key is
37183742returned as a [ ` Buffer ` ] [ ] .
37193743
@@ -3923,6 +3947,47 @@ See the [Web Crypto API documentation][] for details.
39233947
39243948## Notes
39253949
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+
39263991### Legacy streams API (prior to Node.js 0.10)
39273992
39283993The 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.
43844449[ AEAD algorithms ] : https://en.wikipedia.org/wiki/Authenticated_encryption
43854450[ CCM mode ] : #crypto_ccm_mode
43864451[ 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
43874453[ Crypto constants ] : #crypto_crypto_constants_1
43884454[ HTML 5.2 ] : https://www.w3.org/TR/html52/changes.html#features-removed
43894455[ 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.
44064472[ `EVP_BytesToKey` ] : https://www.openssl.org/docs/man1.1.0/crypto/EVP_BytesToKey.html
44074473[ `KeyObject` ] : #crypto_class_keyobject
44084474[ `Sign` ] : #crypto_class_sign
4475+ [ `String.prototype.normalize()` ] : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
44094476[ `UV_THREADPOOL_SIZE` ] : cli.md#cli_uv_threadpool_size_size
44104477[ `Verify` ] : #crypto_class_verify
44114478[ `cipher.final()` ] : #crypto_cipher_final_outputencoding
0 commit comments