@@ -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 sequencs.
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
0 commit comments