summaryrefslogtreecommitdiff
path: root/doc/api/crypto.md
diff options
context:
space:
mode:
authorTobias Nießen <tniessen@tnie.de>2018-09-20 19:53:44 +0200
committerTobias Nießen <tniessen@tnie.de>2018-12-24 14:50:16 +0100
commit823d86c47ce15fba8875fcebd412593b02aab362 (patch)
treea023dac2cbda38b6e194c7324e501e4054715af5 /doc/api/crypto.md
parent5570df407aae1e329955b1093e0e5b8bde270213 (diff)
downloadandroid-node-v8-823d86c47ce15fba8875fcebd412593b02aab362.tar.gz
android-node-v8-823d86c47ce15fba8875fcebd412593b02aab362.tar.bz2
android-node-v8-823d86c47ce15fba8875fcebd412593b02aab362.zip
crypto: add key object API
This commit makes multiple important changes: 1. A new key object API is introduced. The KeyObject class itself is not exposed to users, instead, several new APIs can be used to construct key objects: createSecretKey, createPrivateKey and createPublicKey. The new API also allows to convert between different key formats, and even though the API itself is not compatible to the WebCrypto standard in any way, it makes interoperability much simpler. 2. Key objects can be used instead of the raw key material in all relevant crypto APIs. 3. The handling of asymmetric keys has been unified and greatly improved. Node.js now fully supports both PEM-encoded and DER-encoded public and private keys. 4. Conversions between buffers and strings have been moved to native code for sensitive data such as symmetric keys due to security considerations such as zeroing temporary buffers. 5. For compatibility with older versions of the crypto API, this change allows to specify Buffers and strings as the "passphrase" option when reading or writing an encoded key. Note that this can result in unexpected behavior if the password contains a null byte. PR-URL: https://github.com/nodejs/node/pull/24234 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'doc/api/crypto.md')
-rw-r--r--doc/api/crypto.md278
1 files changed, 218 insertions, 60 deletions
diff --git a/doc/api/crypto.md b/doc/api/crypto.md
index 736ac360c9..017eb91e67 100644
--- a/doc/api/crypto.md
+++ b/doc/api/crypto.md
@@ -1101,6 +1101,81 @@ encoding of `'utf8'` is enforced. If `data` is a [`Buffer`][], `TypedArray`, or
This can be called many times with new data as it is streamed.
+## Class: KeyObject
+<!-- YAML
+added: REPLACEME
+-->
+
+Node.js uses an internal `KeyObject` class which should not be accessed
+directly. Instead, factory functions exist to create instances of this class
+in a secure manner, see [`crypto.createSecretKey()`][],
+[`crypto.createPublicKey()`][] and [`crypto.createPrivateKey()`][]. A
+`KeyObject` can represent a symmetric or asymmetric key, and each kind of key
+exposes different functions.
+
+Most applications should consider using the new `KeyObject` API instead of
+passing keys as strings or `Buffer`s due to improved security features.
+
+### keyObject.asymmetricKeyType
+<!-- YAML
+added: REPLACEME
+-->
+* {string}
+
+For asymmetric keys, this property represents the type of the embedded key
+(`'rsa'`, `'dsa'` or `'ec'`). This property is `undefined` for symmetric keys.
+
+### keyObject.export([options])
+<!-- YAML
+added: REPLACEME
+-->
+* `options`: {Object}
+* Returns: {string | Buffer}
+
+For symmetric keys, this function allocates a `Buffer` containing the key
+material and ignores any options.
+
+For asymmetric keys, the `options` parameter is used to determine the export
+format.
+
+For public keys, the following encoding options can be used:
+
+* `type`: {string} Must be one of `'pkcs1'` (RSA only) or `'spki'`.
+* `format`: {string} Must be `'pem'` or `'der'`.
+
+For private keys, the following encoding options can be used:
+
+* `type`: {string} Must be one of `'pkcs1'` (RSA only), `'pkcs8'` or
+ `'sec1'` (EC only).
+* `format`: {string} Must be `'pem'` or `'der'`.
+* `cipher`: {string} If specified, the private key will be encrypted with
+ the given `cipher` and `passphrase` using PKCS#5 v2.0 password based
+ encryption.
+* `passphrase`: {string | Buffer} The passphrase to use for encryption, see
+ `cipher`.
+
+When PEM encoding was selected, the result will be a string, otherwise it will
+be a buffer containing the data encoded as DER.
+
+### keyObject.symmetricSize
+<!-- YAML
+added: REPLACEME
+-->
+* {number}
+
+For secret keys, this property represents the size of the key in bytes. This
+property is `undefined` for asymmetric keys.
+
+### keyObject.type
+<!-- YAML
+added: REPLACEME
+-->
+* {string}
+
+Depending on the type of this `KeyObject`, this property is either
+`'secret'` for secret (symmetric) keys, `'public'` for public (asymmetric) keys
+or `'private'` for private (asymmetric) keys.
+
## Class: Sign
<!-- YAML
added: v0.1.92
@@ -1169,13 +1244,14 @@ console.log(sign.sign(privateKey, 'hex'));
<!-- YAML
added: v0.1.92
changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/24234
+ description: This function now supports key objects.
- version: v8.0.0
pr-url: https://github.com/nodejs/node/pull/11705
description: Support for RSASSA-PSS and additional options was added.
-->
-* `privateKey` {string | Object}
- - `key` {string}
- - `passphrase` {string}
+* `privateKey` {Object | string | Buffer | KeyObject}
- `padding` {integer}
- `saltLength` {integer}
* `outputEncoding` {string} The [encoding][] of the return value.
@@ -1184,12 +1260,10 @@ changes:
Calculates the signature on all the data passed through using either
[`sign.update()`][] or [`sign.write()`][stream-writable-write].
-The `privateKey` argument can be an object or a string. If `privateKey` is a
-string, it is treated as a raw key with no passphrase. If `privateKey` is an
-object, it must contain one or more of the following properties:
+If `privateKey` is not a [`KeyObject`][], this function behaves as if
+`privateKey` had been passed to [`crypto.createPrivateKey()`][]. If it is an
+object, the following additional properties can be passed:
-* `key`: {string} - PEM encoded private key (required)
-* `passphrase`: {string} - passphrase for the private key
* `padding`: {integer} - Optional padding value for RSA, one of the following:
* `crypto.constants.RSA_PKCS1_PADDING` (default)
* `crypto.constants.RSA_PKCS1_PSS_PADDING`
@@ -1299,18 +1373,20 @@ changes:
pr-url: https://github.com/nodejs/node/pull/11705
description: Support for RSASSA-PSS and additional options was added.
-->
-* `object` {string | Object}
+* `object` {Object | string | Buffer | KeyObject}
+ - `padding` {integer}
+ - `saltLength` {integer}
* `signature` {string | Buffer | TypedArray | DataView}
* `signatureEncoding` {string} The [encoding][] of the `signature` string.
* Returns: {boolean} `true` or `false` depending on the validity of the
signature for the data and public key.
Verifies the provided data using the given `object` and `signature`.
-The `object` argument can be either a string containing a PEM encoded object,
-which can be an RSA public key, a DSA public key, or an X.509 certificate,
-or an object with one or more of the following properties:
-* `key`: {string} - PEM encoded public key (required)
+If `object` is not a [`KeyObject`][], this function behaves as if
+`object` had been passed to [`crypto.createPublicKey()`][]. If it is an
+object, the following additional properties can be passed:
+
* `padding`: {integer} - Optional padding value for RSA, one of the following:
* `crypto.constants.RSA_PKCS1_PADDING` (default)
* `crypto.constants.RSA_PKCS1_PSS_PADDING`
@@ -1436,6 +1512,9 @@ Adversaries][] for details.
<!-- YAML
added: v0.1.94
changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/24234
+ description: The `key` argument can now be a `KeyObject`.
- version: v11.2.0
pr-url: https://github.com/nodejs/node/pull/24081
description: The cipher `chacha20-poly1305` is now supported.
@@ -1452,7 +1531,7 @@ changes:
need an initialization vector.
-->
* `algorithm` {string}
-* `key` {string | Buffer | TypedArray | DataView}
+* `key` {string | Buffer | TypedArray | DataView | KeyObject}
* `iv` {string | Buffer | TypedArray | DataView}
* `options` {Object} [`stream.transform` options][]
* Returns: {Cipher}
@@ -1474,7 +1553,8 @@ display the available cipher algorithms.
The `key` is the raw key used by the `algorithm` and `iv` is an
[initialization vector][]. Both arguments must be `'utf8'` encoded strings,
-[Buffers][`Buffer`], `TypedArray`, or `DataView`s. If the cipher does not need
+[Buffers][`Buffer`], `TypedArray`, or `DataView`s. The `key` may optionally be
+a [`KeyObject`][] of type `secret`. If the cipher does not need
an initialization vector, `iv` may be `null`.
Initialization vectors should be unpredictable and unique; ideally, they will be
@@ -1525,6 +1605,9 @@ to create the `Decipher` object.
<!-- YAML
added: v0.1.94
changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/24234
+ description: The `key` argument can now be a `KeyObject`.
- version: v11.2.0
pr-url: https://github.com/nodejs/node/pull/24081
description: The cipher `chacha20-poly1305` is now supported.
@@ -1563,7 +1646,8 @@ display the available cipher algorithms.
The `key` is the raw key used by the `algorithm` and `iv` is an
[initialization vector][]. Both arguments must be `'utf8'` encoded strings,
-[Buffers][`Buffer`], `TypedArray`, or `DataView`s. If the cipher does not need
+[Buffers][`Buffer`], `TypedArray`, or `DataView`s. The `key` may optionally be
+a [`KeyObject`][] of type `secret`. If the cipher does not need
an initialization vector, `iv` may be `null`.
Initialization vectors should be unpredictable and unique; ideally, they will be
@@ -1674,9 +1758,13 @@ input.on('readable', () => {
### crypto.createHmac(algorithm, key[, options])
<!-- YAML
added: v0.1.94
+changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/24234
+ description: The `key` argument can now be a `KeyObject`.
-->
* `algorithm` {string}
-* `key` {string | Buffer | TypedArray | DataView}
+* `key` {string | Buffer | TypedArray | DataView | KeyObject}
* `options` {Object} [`stream.transform` options][]
* Returns: {Hmac}
@@ -1689,7 +1777,8 @@ On recent releases of OpenSSL, `openssl list -digest-algorithms`
(`openssl list-message-digest-algorithms` for older versions of OpenSSL) will
display the available digest algorithms.
-The `key` is the HMAC key used to generate the cryptographic HMAC hash.
+The `key` is the HMAC key used to generate the cryptographic HMAC hash. If it is
+a [`KeyObject`][], its type must be `secret`.
Example: generating the sha256 HMAC of a file
@@ -1711,6 +1800,47 @@ input.on('readable', () => {
});
```
+### crypto.createPrivateKey(key)
+<!-- YAML
+added: REPLACEME
+-->
+* `key` {Object | string | Buffer}
+ - `key`: {string | Buffer} The key material, either in PEM or DER format.
+ - `format`: {string} Must be `'pem'` or `'der'`. **Default:** `'pem'`.
+ - `type`: {string} Must be `'pkcs1'`, `'pkcs8'` or `'sec1'`. This option is
+ required only if the `format` is `'der'` and ignored if it is `'pem'`.
+ - `passphrase`: {string | Buffer} The passphrase to use for decryption.
+* Returns: {KeyObject}
+
+Creates and returns a new key object containing a private key. If `key` is a
+string or `Buffer`, `format` is assumed to be `'pem'`; otherwise, `key`
+must be an object with the properties described above.
+
+### crypto.createPublicKey(key)
+<!-- YAML
+added: REPLACEME
+-->
+* `key` {Object | string | Buffer}
+ - `key`: {string | Buffer}
+ - `format`: {string} Must be `'pem'` or `'der'`. **Default:** `'pem'`.
+ - `type`: {string} Must be `'pkcs1'` or `'spki'`. This option is required
+ only if the `format` is `'der'`.
+* Returns: {KeyObject}
+
+Creates and returns a new key object containing a public key. If `key` is a
+string or `Buffer`, `format` is assumed to be `'pem'`; otherwise, `key`
+must be an object with the properties described above.
+
+### crypto.createSecretKey(key)
+<!-- YAML
+added: REPLACEME
+-->
+* `key` {Buffer}
+* Returns: {KeyObject}
+
+Creates and returns a new key object containing a secret key for symmetric
+encryption or `Hmac`.
+
### crypto.createSign(algorithm[, options])
<!-- YAML
added: v0.1.92
@@ -1740,6 +1870,11 @@ signing algorithms. Optional `options` argument controls the
### crypto.generateKeyPair(type, options, callback)
<!-- YAML
added: v10.12.0
+changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/24234
+ description: The `generateKeyPair` and `generateKeyPairSync` functions now
+ produce key objects if no encoding was specified.
-->
* `type`: {string} Must be `'rsa'`, `'dsa'` or `'ec'`.
* `options`: {Object}
@@ -1747,27 +1882,22 @@ added: v10.12.0
- `publicExponent`: {number} Public exponent (RSA). **Default:** `0x10001`.
- `divisorLength`: {number} Size of `q` in bits (DSA).
- `namedCurve`: {string} Name of the curve to use (EC).
- - `publicKeyEncoding`: {Object}
- - `type`: {string} Must be one of `'pkcs1'` (RSA only) or `'spki'`.
- - `format`: {string} Must be `'pem'` or `'der'`.
- - `privateKeyEncoding`: {Object}
- - `type`: {string} Must be one of `'pkcs1'` (RSA only), `'pkcs8'` or
- `'sec1'` (EC only).
- - `format`: {string} Must be `'pem'` or `'der'`.
- - `cipher`: {string} If specified, the private key will be encrypted with
- the given `cipher` and `passphrase` using PKCS#5 v2.0 password based
- encryption.
- - `passphrase`: {string} The passphrase to use for encryption, see `cipher`.
+ - `publicKeyEncoding`: {Object} See [`keyObject.export()`][].
+ - `privateKeyEncoding`: {Object} See [`keyObject.export()`][].
* `callback`: {Function}
- `err`: {Error}
- - `publicKey`: {string|Buffer}
- - `privateKey`: {string|Buffer}
+ - `publicKey`: {string | Buffer | KeyObject}
+ - `privateKey`: {string | Buffer | KeyObject}
Generates a new asymmetric key pair of the given `type`. Only RSA, DSA and EC
are currently supported.
+If a `publicKeyEncoding` or `privateKeyEncoding` was specified, this function
+behaves as if [`keyObject.export()`][] had been called on its result. Otherwise,
+the respective part of the key is returned as a [`KeyObject`].
+
It is recommended to encode public keys as `'spki'` and private keys as
-`'pkcs8'` with encryption:
+`'pkcs8'` with encryption for long-term storage:
```js
const { generateKeyPair } = require('crypto');
@@ -1789,11 +1919,7 @@ generateKeyPair('rsa', {
```
On completion, `callback` will be called with `err` set to `undefined` and
-`publicKey` / `privateKey` representing the generated key pair. When PEM
-encoding was selected, the result will be a string, otherwise it will be a
-buffer containing the data encoded as DER. Note that Node.js itself does not
-accept DER, it is supported for interoperability with other libraries such as
-WebCrypto only.
+`publicKey` / `privateKey` representing the generated key pair.
If this method is invoked as its [`util.promisify()`][]ed version, it returns
a `Promise` for an `Object` with `publicKey` and `privateKey` properties.
@@ -1801,6 +1927,11 @@ a `Promise` for an `Object` with `publicKey` and `privateKey` properties.
### crypto.generateKeyPairSync(type, options)
<!-- YAML
added: v10.12.0
+changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/24234
+ description: The `generateKeyPair` and `generateKeyPairSync` functions now
+ produce key objects if no encoding was specified.
-->
* `type`: {string} Must be `'rsa'`, `'dsa'` or `'ec'`.
* `options`: {Object}
@@ -1818,10 +1949,11 @@ added: v10.12.0
- `cipher`: {string} If specified, the private key will be encrypted with
the given `cipher` and `passphrase` using PKCS#5 v2.0 password based
encryption.
- - `passphrase`: {string} The passphrase to use for encryption, see `cipher`.
+ - `passphrase`: {string | Buffer} The passphrase to use for encryption, see
+ `cipher`.
* Returns: {Object}
- - `publicKey`: {string|Buffer}
- - `privateKey`: {string|Buffer}
+ - `publicKey`: {string | Buffer | KeyObject}
+ - `privateKey`: {string | Buffer | KeyObject}
Generates a new asymmetric key pair of the given `type`. Only RSA, DSA and EC
are currently supported.
@@ -2062,10 +2194,12 @@ An array of supported digest functions can be retrieved using
### crypto.privateDecrypt(privateKey, buffer)
<!-- YAML
added: v0.11.14
+changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/24234
+ description: This function now supports key objects.
-->
-* `privateKey` {Object | string}
- - `key` {string} A PEM encoded private key.
- - `passphrase` {string} An optional passphrase for the private key.
+* `privateKey` {Object | string | Buffer | KeyObject}
- `padding` {crypto.constants} An optional padding value defined in
`crypto.constants`, which may be: `crypto.constants.RSA_NO_PADDING`,
`crypto.constants.RSA_PKCS1_PADDING`, or
@@ -2076,16 +2210,22 @@ added: v0.11.14
Decrypts `buffer` with `privateKey`. `buffer` was previously encrypted using
the corresponding public key, for example using [`crypto.publicEncrypt()`][].
-`privateKey` can be an object or a string. If `privateKey` is a string, it is
-treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`.
+If `privateKey` is not a [`KeyObject`][], this function behaves as if
+`privateKey` had been passed to [`crypto.createPrivateKey()`][]. If it is an
+object, the `padding` property can be passed. Otherwise, this function uses
+`RSA_PKCS1_OAEP_PADDING`.
### crypto.privateEncrypt(privateKey, buffer)
<!-- YAML
added: v1.1.0
+changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/24234
+ description: This function now supports key objects.
-->
-* `privateKey` {Object | string}
- - `key` {string} A PEM encoded private key.
- - `passphrase` {string} An optional passphrase for the private key.
+* `privateKey` {Object | string | Buffer | KeyObject}
+ - `key` {string | Buffer | KeyObject} A PEM encoded private key.
+ - `passphrase` {string | Buffer} An optional passphrase for the private key.
- `padding` {crypto.constants} An optional padding value defined in
`crypto.constants`, which may be: `crypto.constants.RSA_NO_PADDING` or
`crypto.constants.RSA_PKCS1_PADDING`.
@@ -2095,16 +2235,21 @@ added: v1.1.0
Encrypts `buffer` with `privateKey`. The returned data can be decrypted using
the corresponding public key, for example using [`crypto.publicDecrypt()`][].
-`privateKey` can be an object or a string. If `privateKey` is a string, it is
-treated as the key with no passphrase and will use `RSA_PKCS1_PADDING`.
+If `privateKey` is not a [`KeyObject`][], this function behaves as if
+`privateKey` had been passed to [`crypto.createPrivateKey()`][]. If it is an
+object, the `padding` property can be passed. Otherwise, this function uses
+`RSA_PKCS1_PADDING`.
### crypto.publicDecrypt(key, buffer)
<!-- YAML
added: v1.1.0
+changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/24234
+ description: This function now supports key objects.
-->
-* `key` {Object | string}
- - `key` {string} A PEM encoded public or private key.
- - `passphrase` {string} An optional passphrase for the private key.
+* `key` {Object | string | Buffer | KeyObject}
+ - `passphrase` {string | Buffer} An optional passphrase for the private key.
- `padding` {crypto.constants} An optional padding value defined in
`crypto.constants`, which may be: `crypto.constants.RSA_NO_PADDING` or
`crypto.constants.RSA_PKCS1_PADDING`.
@@ -2114,8 +2259,10 @@ added: v1.1.0
Decrypts `buffer` with `key`.`buffer` was previously encrypted using
the corresponding private key, for example using [`crypto.privateEncrypt()`][].
-`key` can be an object or a string. If `key` is a string, it is treated as
-the key with no passphrase and will use `RSA_PKCS1_PADDING`.
+If `key` is not a [`KeyObject`][], this function behaves as if
+`key` had been passed to [`crypto.createPublicKey()`][]. If it is an
+object, the `padding` property can be passed. Otherwise, this function uses
+`RSA_PKCS1_PADDING`.
Because RSA public keys can be derived from private keys, a private key may
be passed instead of a public key.
@@ -2123,10 +2270,14 @@ be passed instead of a public key.
### crypto.publicEncrypt(key, buffer)
<!-- YAML
added: v0.11.14
+changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/24234
+ description: This function now supports key objects.
-->
-* `key` {Object | string}
- - `key` {string} A PEM encoded public or private key.
- - `passphrase` {string} An optional passphrase for the private key.
+* `key` {Object | string | Buffer | KeyObject}
+ - `key` {string | Buffer | KeyObject} A PEM encoded public or private key.
+ - `passphrase` {string | Buffer} An optional passphrase for the private key.
- `padding` {crypto.constants} An optional padding value defined in
`crypto.constants`, which may be: `crypto.constants.RSA_NO_PADDING`,
`crypto.constants.RSA_PKCS1_PADDING`, or
@@ -2138,8 +2289,10 @@ Encrypts the content of `buffer` with `key` and returns a new
[`Buffer`][] with encrypted content. The returned data can be decrypted using
the corresponding private key, for example using [`crypto.privateDecrypt()`][].
-`key` can be an object or a string. If `key` is a string, it is treated as
-the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`.
+If `key` is not a [`KeyObject`][], this function behaves as if
+`key` had been passed to [`crypto.createPublicKey()`][]. If it is an
+object, the `padding` property can be passed. Otherwise, this function uses
+`RSA_PKCS1_OAEP_PADDING`.
Because RSA public keys can be derived from private keys, a private key may
be passed instead of a public key.
@@ -2917,6 +3070,7 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL.
[`Buffer`]: buffer.html
[`EVP_BytesToKey`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_BytesToKey.html
+[`KeyObject`]: #crypto_class_keyobject
[`UV_THREADPOOL_SIZE`]: cli.html#cli_uv_threadpool_size_size
[`cipher.final()`]: #crypto_cipher_final_outputencoding
[`cipher.update()`]: #crypto_cipher_update_data_inputencoding_outputencoding
@@ -2928,6 +3082,9 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL.
[`crypto.createECDH()`]: #crypto_crypto_createecdh_curvename
[`crypto.createHash()`]: #crypto_crypto_createhash_algorithm_options
[`crypto.createHmac()`]: #crypto_crypto_createhmac_algorithm_key_options
+[`crypto.createPrivateKey()`]: #crypto_crypto_createprivatekey_key
+[`crypto.createPublicKey()`]: #crypto_crypto_createpublickey_key
+[`crypto.createSecretKey()`]: #crypto_crypto_createsecretkey_key
[`crypto.createSign()`]: #crypto_crypto_createsign_algorithm_options
[`crypto.createVerify()`]: #crypto_crypto_createverify_algorithm_options
[`crypto.getCurves()`]: #crypto_crypto_getcurves
@@ -2949,6 +3106,7 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL.
[`hash.update()`]: #crypto_hash_update_data_inputencoding
[`hmac.digest()`]: #crypto_hmac_digest_encoding
[`hmac.update()`]: #crypto_hmac_update_data_inputencoding
+[`keyObject.export()`]: #crypto_keyobject_export_options
[`sign.sign()`]: #crypto_sign_sign_privatekey_outputencoding
[`sign.update()`]: #crypto_sign_update_data_inputencoding
[`stream.Writable` options]: stream.html#stream_constructor_new_stream_writable_options