X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=doc%2Fapi%2Fcrypto.markdown;h=29fd956a7793d2587c626ab01fd0d8229a6be5be;hb=86d2af58d67847dc36becdd5436d600afacb0f9c;hp=2ebdc1fb7a15483ea10c2021863177c9f26ef08a;hpb=9920ae67b53283192a7396cad63f6d92b80f1a95;p=platform%2Fupstream%2Fnodejs.git diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown index 2ebdc1f..29fd956 100644 --- a/doc/api/crypto.markdown +++ b/doc/api/crypto.markdown @@ -1,641 +1,1407 @@ # Crypto - Stability: 2 - Unstable; API changes are being discussed for - future versions. Breaking changes will be minimized. See below. + Stability: 2 - Stable + +The `crypto` module provides cryptographic functionality that includes a set of +wrappers for OpenSSL's hash, HMAC, cipher, decipher, sign and verify functions. Use `require('crypto')` to access this module. -The crypto module offers a way of encapsulating secure credentials to be -used as part of a secure HTTPS net or http connection. +```js +const crypto = require('crypto'); -It also offers a set of wrappers for OpenSSL's hash, hmac, cipher, -decipher, sign and verify methods. +const secret = 'abcdefg'; +const hash = crypto.createHmac('sha256', secret) + .update('I love cupcakes') + .digest('hex'); +console.log(hash); + // Prints: + // c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e +``` +## Class: Certificate -## crypto.setEngine(engine, [flags]) +SPKAC is a Certificate Signing Request mechanism originally implemented by +Netscape and now specified formally as part of [HTML5's `keygen` element][]. -Load and set engine for some/all OpenSSL functions (selected by flags). +The `crypto` module provides the `Certificate` class for working with SPKAC +data. The most common usage is handling output generated by the HTML5 +`` element. Node.js uses [OpenSSL's SPKAC implementation][] internally. -`engine` could be either an id or a path to the to the engine's shared library. +### new crypto.Certificate() -`flags` is optional and has `ENGINE_METHOD_ALL` value by default. It could take -one of or mix of following flags (defined in `constants` module): +Instances of the `Certificate` class can be created using the `new` keyword +or by calling `crypto.Certificate()` as a function: -* `ENGINE_METHOD_RSA` -* `ENGINE_METHOD_DSA` -* `ENGINE_METHOD_DH` -* `ENGINE_METHOD_RAND` -* `ENGINE_METHOD_ECDH` -* `ENGINE_METHOD_ECDSA` -* `ENGINE_METHOD_CIPHERS` -* `ENGINE_METHOD_DIGESTS` -* `ENGINE_METHOD_STORE` -* `ENGINE_METHOD_PKEY_METH` -* `ENGINE_METHOD_PKEY_ASN1_METH` -* `ENGINE_METHOD_ALL` -* `ENGINE_METHOD_NONE` +```js +const crypto = require('crypto'); +const cert1 = new crypto.Certificate(); +const cert2 = crypto.Certificate(); +``` -## crypto.getCiphers() +### certificate.exportChallenge(spkac) -Returns an array with the names of the supported ciphers. +The `spkac` data structure includes a public key and a challenge. The +`certificate.exportChallenge()` returns the challenge component in the +form of a Node.js [`Buffer`][]. The `spkac` argument can be either a string +or a [`Buffer`][]. -Example: +```js +const cert = require('crypto').Certificate(); +const spkac = getSpkacSomehow(); +const challenge = cert.exportChallenge(spkac); +console.log(challenge.toString('utf8')); + // Prints the challenge as a UTF8 string +``` - var ciphers = crypto.getCiphers(); - console.log(ciphers); // ['AES-128-CBC', 'AES-128-CBC-HMAC-SHA1', ...] +### certificate.exportPublicKey(spkac) +The `spkac` data structure includes a public key and a challenge. The +`certificate.exportPublicKey()` returns the public key component in the +form of a Node.js [`Buffer`][]. The `spkac` argument can be either a string +or a [`Buffer`][]. -## crypto.getHashes() +```js +const cert = require('crypto').Certificate(); +const spkac = getSpkacSomehow(); +const publicKey = cert.exportPublicKey(spkac); +console.log(publicKey); + // Prints the public key as +``` -Returns an array with the names of the supported hash algorithms. +### certificate.verifySpkac(spkac) -Example: +Returns `true` if the given `spkac` data structure is valid, `false` otherwise. +The `spkac` argument must be a Node.js [`Buffer`][]. - var hashes = crypto.getHashes(); - console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...] +```js +const cert = require('crypto').Certificate(); +const spkac = getSpkacSomehow(); +console.log(cert.verifySpkac(new Buffer(spkac))); + // Prints true or false +``` +## Class: Cipher -## crypto.createCredentials(details) +Instances of the `Cipher` class are used to encrypt data. The class can be +used in one of two ways: -Creates a credentials object, with the optional details being a -dictionary with keys: +- As a [stream][] that is both readable and writable, where plain unencrypted + data is written to produce encrypted data on the readable side, or +- Using the [`cipher.update()`][] and [`cipher.final()`][] methods to produce + the encrypted data. -* `pfx` : A string or buffer holding the PFX or PKCS12 encoded private - key, certificate and CA certificates -* `key` : A string holding the PEM encoded private key -* `passphrase` : A string of passphrase for the private key or pfx -* `cert` : A string holding the PEM encoded certificate -* `ca` : Either a string or list of strings of PEM encoded CA - certificates to trust. -* `crl` : Either a string or list of strings of PEM encoded CRLs - (Certificate Revocation List) -* `ciphers`: A string describing the ciphers to use or exclude. - Consult - - for details on the format. +The [`crypto.createCipher()`][] or [`crypto.createCipheriv()`][] methods are +used to create `Cipher` instances. `Cipher` objects are not to be created +directly using the `new` keyword. -If no 'ca' details are given, then node.js will use the default -publicly trusted list of CAs as given in -. +Example: Using `Cipher` objects as streams: +```js +const crypto = require('crypto'); +const cipher = crypto.createCipher('aes192', 'a password'); -## crypto.createHash(algorithm) +var encrypted = ''; +cipher.on('readable', () => { + var data = cipher.read(); + if (data) + encrypted += data.toString('hex'); +}); +cipher.on('end', () => { + console.log(encrypted); + // Prints: ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504 +}); -Creates and returns a hash object, a cryptographic hash with the given -algorithm which can be used to generate hash digests. +cipher.write('some clear text data'); +cipher.end(); +``` -`algorithm` is dependent on the available algorithms supported by the -version of OpenSSL on the platform. Examples are `'sha1'`, `'md5'`, -`'sha256'`, `'sha512'`, etc. On recent releases, `openssl -list-message-digest-algorithms` will display the available digest -algorithms. +Example: Using `Cipher` and piped streams: -Example: this program that takes the sha1 sum of a file +```js +const crypto = require('crypto'); +const fs = require('fs'); +const cipher = crypto.createCipher('aes192', 'a password'); - var filename = process.argv[2]; - var crypto = require('crypto'); - var fs = require('fs'); +const input = fs.createReadStream('test.js'); +const output = fs.createWriteStream('test.enc'); - var shasum = crypto.createHash('sha1'); +input.pipe(cipher).pipe(output); +``` - var s = fs.ReadStream(filename); - s.on('data', function(d) { - shasum.update(d); - }); +Example: Using the [`cipher.update()`][] and [`cipher.final()`][] methods: - s.on('end', function() { - var d = shasum.digest('hex'); - console.log(d + ' ' + filename); - }); +```js +const crypto = require('crypto'); +const cipher = crypto.createCipher('aes192', 'a password'); -## Class: Hash +var encrypted = cipher.update('some clear text data', 'utf8', 'hex'); +encrypted += cipher.final('hex'); +console.log(encrypted); + // Prints: ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504 +``` -The class for creating hash digests of data. +### cipher.final([output_encoding]) -It is a [stream](stream.html) that is both readable and writable. The -written data is used to compute the hash. Once the writable side of -the stream is ended, use the `read()` method to get the computed hash -digest. The legacy `update` and `digest` methods are also supported. +Returns any remaining enciphered contents. If `output_encoding` +parameter is one of `'binary'`, `'base64'` or `'hex'`, a string is returned. +If an `output_encoding` is not provided, a [`Buffer`][] is returned. -Returned by `crypto.createHash`. +Once the `cipher.final()` method has been called, the `Cipher` object can no +longer be used to encrypt data. Attempts to call `cipher.final()` more than +once will result in an error being thrown. -### hash.update(data, [input_encoding]) +### cipher.setAAD(buffer) -Updates the hash content with the given `data`, the encoding of which -is given in `input_encoding` and can be `'utf8'`, `'ascii'` or -`'binary'`. If no encoding is provided and the input is a string an -encoding of `'binary'` is enforced. If `data` is a `Buffer` then -`input_encoding` is ignored. +When using an authenticated encryption mode (only `GCM` is currently +supported), the `cipher.setAAD()` method sets the value used for the +_additional authenticated data_ (AAD) input parameter. -This can be called many times with new data as it is streamed. +### cipher.getAuthTag() -### hash.digest([encoding]) +When using an authenticated encryption mode (only `GCM` is currently +supported), the `cipher.getAuthTag()` method returns a [`Buffer`][] containing +the _authentication tag_ that has been computed from the given data. -Calculates the digest of all of the passed data to be hashed. The -`encoding` can be `'hex'`, `'binary'` or `'base64'`. If no encoding -is provided, then a buffer is returned. +The `cipher.getAuthTag()` method should only be called after encryption has +been completed using the [`cipher.final()`][] method. -Note: `hash` object can not be used after `digest()` method has been -called. +### cipher.setAutoPadding(auto_padding=true) +When using block encryption algorithms, the `Cipher` class will automatically +add padding to the input data to the appropriate block size. To disable the +default padding call `cipher.setAutoPadding(false)`. -## crypto.createHmac(algorithm, key) +When `auto_padding` is `false`, the length of the entire input data must be a +multiple of the cipher's block size or [`cipher.final()`][] will throw an Error. +Disabling automatic padding is useful for non-standard padding, for instance +using `0x0` instead of PKCS padding. -Creates and returns a hmac object, a cryptographic hmac with the given -algorithm and key. +The `cipher.setAutoPadding()` method must be called before [`cipher.final()`][]. -It is a [stream](stream.html) that is both readable and writable. The -written data is used to compute the hmac. Once the writable side of -the stream is ended, use the `read()` method to get the computed -digest. The legacy `update` and `digest` methods are also supported. +### cipher.update(data[, input_encoding][, output_encoding]) -`algorithm` is dependent on the available algorithms supported by -OpenSSL - see createHash above. `key` is the hmac key to be used. +Updates the cipher with `data`. If the `input_encoding` argument is given, +it's value must be one of `'utf8'`, `'ascii'`, or `'binary'` and the `data` +argument is a string using the specified encoding. If the `input_encoding` +argument is not given, `data` must be a [`Buffer`][]. If `data` is a +[`Buffer`][] then `input_encoding` is ignored. -## Class: Hmac +The `output_encoding` specifies the output format of the enciphered +data, and can be `'binary'`, `'base64'` or `'hex'`. If the `output_encoding` +is specified, a string using the specified encoding is returned. If no +`output_encoding` is provided, a [`Buffer`][] is returned. -Class for creating cryptographic hmac content. +The `cipher.update()` method can be called multiple times with new data until +[`cipher.final()`][] is called. Calling `cipher.update()` after +[`cipher.final()`][] will result in an error being thrown. -Returned by `crypto.createHmac`. +## Class: Decipher -### hmac.update(data) +Instances of the `Decipher` class are used to decrypt data. The class can be +used in one of two ways: -Update the hmac content with the given `data`. This can be called -many times with new data as it is streamed. +- As a [stream][] that is both readable and writable, where plain encrypted + data is written to produce unencrypted data on the readable side, or +- Using the [`decipher.update()`][] and [`decipher.final()`][] methods to + produce the unencrypted data. -### hmac.digest([encoding]) +The [`crypto.createDecipher()`][] or [`crypto.createDecipheriv()`][] methods are +used to create `Decipher` instances. `Decipher` objects are not to be created +directly using the `new` keyword. -Calculates the digest of all of the passed data to the hmac. The -`encoding` can be `'hex'`, `'binary'` or `'base64'`. If no encoding -is provided, then a buffer is returned. +Example: Using `Decipher` objects as streams: -Note: `hmac` object can not be used after `digest()` method has been -called. +```js +const crypto = require('crypto'); +const decipher = crypto.createDecipher('aes192', 'a password'); +var decrypted = ''; +decipher.on('readable', () => { + var data = decipher.read(); + if (data) + decrypted += data.toString('utf8'); +}); +decipher.on('end', () => { + console.log(decrypted); + // Prints: some clear text data +}); -## crypto.createCipher(algorithm, password) +var encrypted = 'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504'; +decipher.write(encrypted, 'hex'); +decipher.end(); +``` -Creates and returns a cipher object, with the given algorithm and -password. +Example: Using `Decipher` and piped streams: -`algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On -recent releases, `openssl list-cipher-algorithms` will display the -available cipher algorithms. `password` is used to derive key and IV, -which must be a `'binary'` encoded string or a [buffer](buffer.html). +```js +const crypto = require('crypto'); +const fs = require('fs'); +const decipher = crypto.createDecipher('aes192', 'a password'); -It is a [stream](stream.html) that is both readable and writable. The -written data is used to compute the hash. Once the writable side of -the stream is ended, use the `read()` method to get the computed hash -digest. The legacy `update` and `digest` methods are also supported. +const input = fs.createReadStream('test.enc'); +const output = fs.createWriteStream('test.js'); -## crypto.createCipheriv(algorithm, key, iv) +input.pipe(decipher).pipe(output); +``` -Creates and returns a cipher object, with the given algorithm, key and -iv. +Example: Using the [`decipher.update()`][] and [`decipher.final()`][] methods: -`algorithm` is the same as the argument to `createCipher()`. `key` is -the raw key used by the algorithm. `iv` is an [initialization -vector](http://en.wikipedia.org/wiki/Initialization_vector). +```js +const crypto = require('crypto'); +const decipher = crypto.createDecipher('aes192', 'a password'); -`key` and `iv` must be `'binary'` encoded strings or -[buffers](buffer.html). +var encrypted = 'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504'; +var decrypted = decipher.update(encrypted, 'hex', 'utf8'); +decrypted += decipher.final('utf8'); +console.log(decrypted); + // Prints: some clear text data +``` -## Class: Cipher +### decipher.final([output_encoding]) + +Returns any remaining deciphered contents. If `output_encoding` +parameter is one of `'binary'`, `'base64'` or `'hex'`, a string is returned. +If an `output_encoding` is not provided, a [`Buffer`][] is returned. + +Once the `decipher.final()` method has been called, the `Decipher` object can +no longer be used to decrypt data. Attempts to call `decipher.final()` more +than once will result in an error being thrown. + +### decipher.setAAD(buffer) -Class for encrypting data. +When using an authenticated encryption mode (only `GCM` is currently +supported), the `cipher.setAAD()` method sets the value used for the +_additional authenticated data_ (AAD) input parameter. + +### decipher.setAuthTag(buffer) + +When using an authenticated encryption mode (only `GCM` is currently +supported), the `decipher.setAuthTag()` method is used to pass in the +received _authentication tag_. If no tag is provided, or if the cipher text +has been tampered with, [`decipher.final()`][] with throw, indicating that the +cipher text should be discarded due to failed authentication. + +### decipher.setAutoPadding(auto_padding=true) -Returned by `crypto.createCipher` and `crypto.createCipheriv`. +When data has been encrypted without standard block padding, calling +`decipher.setAutoPadding(false)` will disable automatic padding to prevent +[`decipher.final()`][] from checking for and removing padding. -Cipher objects are [streams](stream.html) that are both readable and -writable. The written plain text data is used to produce the -encrypted data on the readable side. The legacy `update` and `final` -methods are also supported. +Turning auto padding off will only work if the input data's length is a +multiple of the ciphers block size. -### cipher.update(data, [input_encoding], [output_encoding]) +The `decipher.setAutoPadding()` method must be called before +[`decipher.update()`][]. -Updates the cipher with `data`, the encoding of which is given in -`input_encoding` and can be `'utf8'`, `'ascii'` or `'binary'`. If no -encoding is provided, then a buffer is expected. -If `data` is a `Buffer` then `input_encoding` is ignored. +### decipher.update(data[, input_encoding][, output_encoding]) + +Updates the decipher with `data`. If the `input_encoding` argument is given, +it's value must be one of `'binary'`, `'base64'`, or `'hex'` and the `data` +argument is a string using the specified encoding. If the `input_encoding` +argument is not given, `data` must be a [`Buffer`][]. If `data` is a +[`Buffer`][] then `input_encoding` is ignored. The `output_encoding` specifies the output format of the enciphered -data, and can be `'binary'`, `'base64'` or `'hex'`. If no encoding is -provided, then a buffer is returned. +data, and can be `'binary'`, `'ascii'` or `'utf8'`. If the `output_encoding` +is specified, a string using the specified encoding is returned. If no +`output_encoding` is provided, a [`Buffer`][] is returned. -Returns the enciphered contents, and can be called many times with new -data as it is streamed. +The `decipher.update()` method can be called multiple times with new data until +[`decipher.final()`][] is called. Calling `decipher.update()` after +[`decipher.final()`][] will result in an error being thrown. -### cipher.final([output_encoding]) +## Class: DiffieHellman -Returns any remaining enciphered contents, with `output_encoding` -being one of: `'binary'`, `'base64'` or `'hex'`. If no encoding is -provided, then a buffer is returned. +The `DiffieHellman` class is a utility for creating Diffie-Hellman key +exchanges. -Note: `cipher` object can not be used after `final()` method has been -called. +Instances of the `DiffieHellman` class can be created using the +[`crypto.createDiffieHellman()`][] function. -### cipher.setAutoPadding(auto_padding=true) +```js +const crypto = require('crypto'); +const assert = require('assert'); -You can disable automatic padding of the input data to block size. If -`auto_padding` is false, the length of the entire input data must be a -multiple of the cipher's block size or `final` will fail. Useful for -non-standard padding, e.g. using `0x0` instead of PKCS padding. You -must call this before `cipher.final`. +// Generate Alice's keys... +const alice = crypto.createDiffieHellman(2048); +const alice_key = alice.generateKeys(); -### cipher.getAuthTag() +// Generate Bob's keys... +const bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator()); +const bob_key = bob.generateKeys(); -For authenticated encryption modes (currently supported: GCM), this -method returns a `Buffer` that represents the _authentication tag_ that -has been computed from the given data. Should be called after -encryption has been completed using the `final` method! +// Exchange and generate the secret... +const alice_secret = alice.computeSecret(bob_key); +const bob_secret = bob.computeSecret(alice_key); -### cipher.setAAD(buffer) +// OK +assert.equal(alice_secret.toString('hex'), bob_secret.toString('hex')); +``` -For authenticated encryption modes (currently supported: GCM), this -method sets the value used for the additional authenticated data (AAD) input -parameter. +### diffieHellman.computeSecret(other_public_key[, input_encoding][, output_encoding]) +Computes the shared secret using `other_public_key` as the other +party's public key and returns the computed shared secret. The supplied +key is interpreted using the specified `input_encoding`, and secret is +encoded using specified `output_encoding`. Encodings can be +`'binary'`, `'hex'`, or `'base64'`. If the `input_encoding` is not +provided, `other_public_key` is expected to be a [`Buffer`][]. -## crypto.createDecipher(algorithm, password) +If `output_encoding` is given a string is returned; otherwise, a +[`Buffer`][] is returned. -Creates and returns a decipher object, with the given algorithm and -key. This is the mirror of the [createCipher()][] above. +### diffieHellman.generateKeys([encoding]) -## crypto.createDecipheriv(algorithm, key, iv) +Generates private and public Diffie-Hellman key values, and returns +the public key in the specified `encoding`. This key should be +transferred to the other party. Encoding can be `'binary'`, `'hex'`, +or `'base64'`. If `encoding` is provided a string is returned; otherwise a +[`Buffer`][] is returned. -Creates and returns a decipher object, with the given algorithm, key -and iv. This is the mirror of the [createCipheriv()][] above. +### diffieHellman.getGenerator([encoding]) -## Class: Decipher +Returns the Diffie-Hellman generator in the specified `encoding`, which can +be `'binary'`, `'hex'`, or `'base64'`. If `encoding` is provided a string is +returned; otherwise a [`Buffer`][] is returned. -Class for decrypting data. +### diffieHellman.getPrime([encoding]) -Returned by `crypto.createDecipher` and `crypto.createDecipheriv`. +Returns the Diffie-Hellman prime in the specified `encoding`, which can +be `'binary'`, `'hex'`, or `'base64'`. If `encoding` is provided a string is +returned; otherwise a [`Buffer`][] is returned. -Decipher objects are [streams](stream.html) that are both readable and -writable. The written enciphered data is used to produce the -plain-text data on the the readable side. The legacy `update` and -`final` methods are also supported. +### diffieHellman.getPrivateKey([encoding]) -### decipher.update(data, [input_encoding], [output_encoding]) +Returns the Diffie-Hellman private key in the specified `encoding`, +which can be `'binary'`, `'hex'`, or `'base64'`. If `encoding` is provided a +string is returned; otherwise a [`Buffer`][] is returned. -Updates the decipher with `data`, which is encoded in `'binary'`, -`'base64'` or `'hex'`. If no encoding is provided, then a buffer is -expected. -If `data` is a `Buffer` then `input_encoding` is ignored. +### diffieHellman.getPublicKey([encoding]) -The `output_decoding` specifies in what format to return the -deciphered plaintext: `'binary'`, `'ascii'` or `'utf8'`. If no -encoding is provided, then a buffer is returned. +Returns the Diffie-Hellman public key in the specified `encoding`, which +can be `'binary'`, `'hex'`, or `'base64'`. If `encoding` is provided a +string is returned; otherwise a [`Buffer`][] is returned. -### decipher.final([output_encoding]) +### diffieHellman.setPrivateKey(private_key[, encoding]) -Returns any remaining plaintext which is deciphered, with -`output_encoding` being one of: `'binary'`, `'ascii'` or `'utf8'`. If -no encoding is provided, then a buffer is returned. +Sets the Diffie-Hellman private key. If the `encoding` argument is provided +and is either `'binary'`, `'hex'`, or `'base64'`, `private_key` is expected +to be a string. If no `encoding` is provided, `private_key` is expected +to be a [`Buffer`][]. -Note: `decipher` object can not be used after `final()` method has been -called. +### diffieHellman.setPublicKey(public_key[, encoding]) -### decipher.setAutoPadding(auto_padding=true) +Sets the Diffie-Hellman public key. If the `encoding` argument is provided +and is either `'binary'`, `'hex'` or `'base64'`, `public_key` is expected +to be a string. If no `encoding` is provided, `public_key` is expected +to be a [`Buffer`][]. -You can disable auto padding if the data has been encrypted without -standard block padding to prevent `decipher.final` from checking and -removing it. Can only work if the input data's length is a multiple of -the ciphers block size. You must call this before streaming data to -`decipher.update`. +### diffieHellman.verifyError -### decipher.setAuthTag(buffer) +A bit field containing any warnings and/or errors resulting from a check +performed during initialization of the `DiffieHellman` object. -For authenticated encryption modes (currently supported: GCM), this -method must be used to pass in the received _authentication tag_. -If no tag is provided or if the ciphertext has been tampered with, -`final` will throw, thus indicating that the ciphertext should -be discarded due to failed authentication. +The following values are valid for this property (as defined in `constants` +module): -### decipher.setAAD(buffer) +* `DH_CHECK_P_NOT_SAFE_PRIME` +* `DH_CHECK_P_NOT_PRIME` +* `DH_UNABLE_TO_CHECK_GENERATOR` +* `DH_NOT_SUITABLE_GENERATOR` -For authenticated encryption modes (currently supported: GCM), this -method sets the value used for the additional authenticated data (AAD) input -parameter. +## Class: ECDH +The `ECDH` class is a utility for creating Elliptic Curve Diffie-Hellman (ECDH) +key exchanges. -## crypto.createSign(algorithm) +Instances of the `ECDH` class can be created using the +[`crypto.createECDH()`][] function. -Creates and returns a signing object, with the given algorithm. On -recent OpenSSL releases, `openssl list-public-key-algorithms` will -display the available signing algorithms. Examples are `'RSA-SHA256'`. +```js +const crypto = require('crypto'); +const assert = require('assert'); + +// Generate Alice's keys... +const alice = crypto.createECDH('secp521r1'); +const alice_key = alice.generateKeys(); + +// Generate Bob's keys... +const bob = crypto.createECDH('secp521r1'); +const bob_key = bob.generateKeys(); + +// Exchange and generate the secret... +const alice_secret = alice.computeSecret(bob_key); +const bob_secret = bob.computeSecret(alice_key); + +assert(alice_secret, bob_secret); + // OK +``` + +### ecdh.computeSecret(other_public_key[, input_encoding][, output_encoding]) + +Computes the shared secret using `other_public_key` as the other +party's public key and returns the computed shared secret. The supplied +key is interpreted using specified `input_encoding`, and the returned secret +is encoded using the specified `output_encoding`. Encodings can be +`'binary'`, `'hex'`, or `'base64'`. If the `input_encoding` is not +provided, `other_public_key` is expected to be a [`Buffer`][]. + +If `output_encoding` is given a string will be returned; otherwise a +[`Buffer`][] is returned. + +### ecdh.generateKeys([encoding[, format]]) + +Generates private and public EC Diffie-Hellman key values, and returns +the public key in the specified `format` and `encoding`. This key should be +transferred to the other party. + +The `format` arguments specifies point encoding and can be `'compressed'`, +`'uncompressed'`, or `'hybrid'`. If `format` is not specified, the point will +be returned in `'uncompressed'` format. + +The `encoding` argument can be `'binary'`, `'hex'`, or `'base64'`. If +`encoding` is provided a string is returned; otherwise a [`Buffer`][] +is returned. + +### ecdh.getPrivateKey([encoding]) + +Returns the EC Diffie-Hellman private key in the specified `encoding`, +which can be `'binary'`, `'hex'`, or `'base64'`. If `encoding` is provided +a string is returned; otherwise a [`Buffer`][] is returned. + +### ecdh.getPublicKey([encoding[, format]]) + +Returns the EC Diffie-Hellman public key in the specified `encoding` and +`format`. + +The `format` argument specifies point encoding and can be `'compressed'`, +`'uncompressed'`, or `'hybrid'`. If `format` is not specified the point will be +returned in `'uncompressed'` format. + +The `encoding` argument can be `'binary'`, `'hex'`, or `'base64'`. If +`encoding` is specified, a string is returned; otherwise a [`Buffer`][] is +returned. + +### ecdh.setPrivateKey(private_key[, encoding]) + +Sets the EC Diffie-Hellman private key. The `encoding` can be `'binary'`, +`'hex'` or `'base64'`. If `encoding` is provided, `private_key` is expected +to be a string; otherwise `private_key` is expected to be a [`Buffer`][]. If +`private_key` is not valid for the curve specified when the `ECDH` object was +created, an error is thrown. Upon setting the private key, the associated +public point (key) is also generated and set in the ECDH object. + +### ecdh.setPublicKey(public_key[, encoding]) + + Stability: 0 - Deprecated + +Sets the EC Diffie-Hellman public key. Key encoding can be `'binary'`, +`'hex'` or `'base64'`. If `encoding` is provided `public_key` is expected to +be a string; otherwise a [`Buffer`][] is expected. + +Note that there is not normally a reason to call this method because `ECDH` +only requires a private key and the other party's public key to compute the +shared secret. Typically either [`ecdh.generateKeys()`][] or +[`ecdh.setPrivateKey()`][] will be called. The [`ecdh.setPrivateKey()`][] method +attempts to generate the public point/key associated with the private key being +set. + +Example (obtaining a shared secret): + +```js +const crypto = require('crypto'); +const alice = crypto.createECDH('secp256k1'); +const bob = crypto.createECDH('secp256k1'); + +// Note: This is a shortcut way to specify one of Alice's previous private +// keys. It would be unwise to use such a predictable private key in a real +// application. +alice.setPrivateKey( + crypto.createHash('sha256').update('alice', 'utf8').digest() +); + +// Bob uses a newly generated cryptographically strong +// pseudorandom key pair bob.generateKeys(); + +const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); +const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); + +// alice_secret and bob_secret should be the same shared secret value +console.log(alice_secret === bob_secret); +``` + +## Class: Hash + +The `Hash` class is a utility for creating hash digests of data. It can be +used in one of two ways: + +- As a [stream][] that is both readable and writable, where data is written + to produce a computed hash digest on the readable side, or +- Using the [`hash.update()`][] and [`hash.digest()`][] methods to produce the + computed hash. + +The [`crypto.createHash()`][] method is used to create `Hash` instances. `Hash` +objects are not to be created directly using the `new` keyword. + +Example: Using `Hash` objects as streams: + +```js +const crypto = require('crypto'); +const hash = crypto.createHash('sha256'); + +hash.on('readable', () => { + var data = hash.read(); + if (data) + console.log(data.toString('hex')); + // Prints: + // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50 +}); + +hash.write('some data to hash'); +hash.end(); +``` + +Example: Using `Hash` and piped streams: + +```js +const crypto = require('crypto'); +const fs = require('fs'); +const hash = crypto.createHash('sha256'); + +const input = fs.createReadStream('test.js'); +input.pipe(hash).pipe(process.stdout); +``` + +Example: Using the [`hash.update()`][] and [`hash.digest()`][] methods: + +```js +const crypto = require('crypto'); +const hash = crypto.createHash('sha256'); + +hash.update('some data to hash'); +console.log(hash.digest('hex')); + // Prints: + // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50 +``` + +### hash.digest([encoding]) + +Calculates the digest of all of the data passed to be hashed (using the +[`hash.update()`][] method). The `encoding` can be `'hex'`, `'binary'` or +`'base64'`. If `encoding` is provided a string will be returned; otherwise +a [`Buffer`][] is returned. + +The `Hash` object can not be used again after `hash.digest()` method has been +called. Multiple calls will cause an error to be thrown. + +### hash.update(data[, input_encoding]) + +Updates the hash content with the given `data`, the encoding of which +is given in `input_encoding` and can be `'utf8'`, `'ascii'` or +`'binary'`. If `encoding` is not provided, and the `data` is a string, an +encoding of `'binary'` is enforced. If `data` is a [`Buffer`][] then +`input_encoding` is ignored. + +This can be called many times with new data as it is streamed. + +## Class: Hmac + +The `Hmac` Class is a utility for creating cryptographic HMAC digests. It can +be used in one of two ways: + +- As a [stream][] that is both readable and writable, where data is written + to produce a computed HMAC digest on the readable side, or +- Using the [`hmac.update()`][] and [`hmac.digest()`][] methods to produce the + computed HMAC digest. + +The [`crypto.createHmac()`][] method is used to create `Hmac` instances. `Hmac` +objects are not to be created directly using the `new` keyword. + +Example: Using `Hmac` objects as streams: + +```js +const crypto = require('crypto'); +const hmac = crypto.createHmac('sha256', 'a secret'); + +hmac.on('readable', () => { + var data = hmac.read(); + if (data) + console.log(data.toString('hex')); + // Prints: + // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e +}); + +hmac.write('some data to hash'); +hmac.end(); +``` + +Example: Using `Hmac` and piped streams: + +```js +const crypto = require('crypto'); +const fs = require('fs'); +const hmac = crypto.createHmac('sha256', 'a secret'); + +const input = fs.createReadStream('test.js'); +input.pipe(hmac).pipe(process.stdout); +``` + +Example: Using the [`hmac.update()`][] and [`hmac.digest()`][] methods: + +```js +const crypto = require('crypto'); +const hmac = crypto.createHmac('sha256', 'a secret'); + +hmac.update('some data to hash'); +console.log(hmac.digest('hex')); + // Prints: + // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e +``` + +### hmac.digest([encoding]) + +Calculates the HMAC digest of all of the data passed using [`hmac.update()`][]. +The `encoding` can be `'hex'`, `'binary'` or `'base64'`. If `encoding` is +provided a string is returned; otherwise a [`Buffer`][] is returned; + +The `Hmac` object can not be used again after `hmac.digest()` has been +called. Multiple calls to `hmac.digest()` will result in an error being thrown. + +### hmac.update(data[, input_encoding]) + +Updates the `Hmac` content with the given `data`, the encoding of which +is given in `input_encoding` and can be `'utf8'`, `'ascii'` or +`'binary'`. If `encoding` is not provided, and the `data` is a string, an +encoding of `'utf8'` is enforced. If `data` is a [`Buffer`][] then +`input_encoding` is ignored. + +This can be called many times with new data as it is streamed. ## Class: Sign -Class for generating signatures. +The `Sign` Class is a utility for generating signatures. It can be used in one +of two ways: -Returned by `crypto.createSign`. +- As a writable [stream][], where data to be signed is written and the + [`sign.sign()`][] method is used to generate and return the signature, or +- Using the [`sign.update()`][] and [`sign.sign()`][] methods to produce the + signature. -Sign objects are writable [streams](stream.html). The written data is -used to generate the signature. Once all of the data has been -written, the `sign` method will return the signature. The legacy -`update` method is also supported. +The [`crypto.createSign()`][] method is used to create `Sign` instances. `Sign` +objects are not to be created directly using the `new` keyword. -### sign.update(data) +Example: Using `Sign` objects as streams: -Updates the sign object with data. This can be called many times -with new data as it is streamed. +```js +const crypto = require('crypto'); +const sign = crypto.createSign('RSA-SHA256'); -### sign.sign(private_key, [output_format]) +sign.write('some data to sign'); +sign.end(); -Calculates the signature on all the updated data passed through the -sign. +const private_key = getPrivateKeySomehow(); +console.log(sign.sign(private_key, 'hex')); + // Prints the calculated signature +``` -`private_key` can be an object or a string. If `private_key` is a string, it is -treated as the key with no passphrase. +Example: Using the [`sign.update()`][] and [`sign.sign()`][] methods: + +```js +const crypto = require('crypto'); +const sign = crypto.createSign('RSA-SHA256'); + +sign.update('some data to sign'); + +const private_key = getPrivateKeySomehow(); +console.log(sign.sign(private_key, 'hex')); + // Prints the calculated signature +``` + +A [`sign`][] instance can also be created by just passing in the digest +algorithm name, in which case OpenSSL will infer the full signature algorithm +from the type of the PEM-formatted private key, including algorithms that +do not have directly exposed name constants, e.g. 'ecdsa-with-SHA256'. + +Example: signing using ECDSA with SHA256 + +```js +const crypto = require('crypto'); +const sign = crypto.createSign('sha256'); + +sign.update('some data to sign'); + +const private_key = '-----BEGIN EC PRIVATE KEY-----\n' + + 'MHcCAQEEIF+jnWY1D5kbVYDNvxxo/Y+ku2uJPDwS0r/VuPZQrjjVoAoGCCqGSM49\n' + + 'AwEHoUQDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNhB8i3mXyIMq704m2m52FdfKZ2\n' + + 'pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng==\n' + + '-----END EC PRIVATE KEY-----\n'; + +console.log(sign.sign(private_key).toString('hex')); +``` + +### sign.sign(private_key[, output_format]) -`private_key`: +Calculates the signature on all the data passed through using either +[`sign.update()`][] or [`sign.write()`][stream-writable-write]. -* `key` : A string holding the PEM encoded private key -* `passphrase` : A string of passphrase for the private key +The `private_key` argument can be an object or a string. If `private_key` is a +string, it is treated as a raw key with no passphrase. If `private_key` is an +object, it is interpreted as a hash containing two properties: -Returns the signature in `output_format` which can be `'binary'`, -`'hex'` or `'base64'`. If no encoding is provided, then a buffer is +* `key` : {String} - PEM encoded private key +* `passphrase` : {String} - passphrase for the private key + +The `output_format` can specify one of `'binary'`, `'hex'` or `'base64'`. If +`output_format` is provided a string is returned; otherwise a [`Buffer`][] is returned. -Note: `sign` object can not be used after `sign()` method has been -called. +The `Sign` object can not be again used after `sign.sign()` method has been +called. Multiple calls to `sign.sign()` will result in an error being thrown. -## crypto.createVerify(algorithm) +### sign.update(data[, input_encoding]) -Creates and returns a verification object, with the given algorithm. -This is the mirror of the signing object above. +Updates the `Sign` content with the given `data`, the encoding of which +is given in `input_encoding` and can be `'utf8'`, `'ascii'` or +`'binary'`. If `encoding` is not provided, and the `data` is a string, an +encoding of `'utf8'` is enforced. If `data` is a [`Buffer`][] then +`input_encoding` is ignored. + +This can be called many times with new data as it is streamed. ## Class: Verify -Class for verifying signatures. +The `Verify` class is a utility for verifying signatures. It can be used in one +of two ways: + +- As a writable [stream][] where written data is used to validate against the + supplied signature, or +- Using the [`verify.update()`][] and [`verify.verify()`][] methods to verify + the signature. + + The [`crypto.createSign()`][] method is used to create `Sign` instances. + `Sign` objects are not to be created directly using the `new` keyword. + +Example: Using `Verify` objects as streams: + +```js +const crypto = require('crypto'); +const verify = crypto.createVerify('RSA-SHA256'); -Returned by `crypto.createVerify`. +verify.write('some data to sign'); +verify.end(); -Verify objects are writable [streams](stream.html). The written data -is used to validate against the supplied signature. Once all of the -data has been written, the `verify` method will return true if the -supplied signature is valid. The legacy `update` method is also -supported. +const public_key = getPublicKeySomehow(); +const signature = getSignatureToVerify(); +console.log(sign.verify(public_key, signature)); + // Prints true or false +``` -### verifier.update(data) +Example: Using the [`verify.update()`][] and [`verify.verify()`][] methods: -Updates the verifier object with data. This can be called many times -with new data as it is streamed. +```js +const crypto = require('crypto'); +const verify = crypto.createVerify('RSA-SHA256'); -### verifier.verify(object, signature, [signature_format]) +verify.update('some data to sign'); -Verifies the signed data by using the `object` and `signature`. -`object` is a string containing a PEM encoded object, which can be -one of RSA public key, DSA public key, or X.509 certificate. -`signature` is the previously calculated signature for the data, in +const public_key = getPublicKeySomehow(); +const signature = getSignatureToVerify(); +console.log(verify.verify(public_key, signature)); + // Prints true or false +``` + +### verifier.update(data[, input_encoding]) + +Updates the `Verify` content with the given `data`, the encoding of which +is given in `input_encoding` and can be `'utf8'`, `'ascii'` or +`'binary'`. If `encoding` is not provided, and the `data` is a string, an +encoding of `'utf8'` is enforced. If `data` is a [`Buffer`][] then +`input_encoding` is ignored. + +This can be called many times with new data as it is streamed. + +### verifier.verify(object, signature[, signature_format]) + +Verifies the provided data using the given `object` and `signature`. +The `object` argument is a string containing a PEM encoded object, which can be +one an RSA public key, a DSA public key, or an X.509 certificate. +The `signature` argument is the previously calculated signature for the data, in the `signature_format` which can be `'binary'`, `'hex'` or `'base64'`. -If no encoding is specified, then a buffer is expected. +If a `signature_format` is specified, the `signature` is expected to be a +string; otherwise `signature` is expected to be a [`Buffer`][]. -Returns true or false depending on the validity of the signature for +Returns `true` or `false` depending on the validity of the signature for the data and public key. -Note: `verifier` object can not be used after `verify()` method has been -called. +The `verifier` object can not be used again after `verify.verify()` has been +called. Multiple calls to `verify.verify()` will result in an error being +thrown. + +## `crypto` module methods and properties -## crypto.createDiffieHellman(prime_length, [generator]) +### crypto.DEFAULT_ENCODING -Creates a Diffie-Hellman key exchange object and generates a prime of -`prime_length` bits and using an optional specific numeric `generator`. -If no `generator` is specified, then `2` is used. +The default encoding to use for functions that can take either strings +or [buffers][`Buffer`]. The default value is `'buffer'`, which makes methods +default to [`Buffer`][] objects. + +The `crypto.DEFAULT_ENCODING` mechanism is provided for backwards compatibility +with legacy programs that expect `'binary'` to be the default encoding. + +New applications should expect the default to be `'buffer'`. This property may +become deprecated in a future Node.js release. + +### crypto.createCipher(algorithm, password) + +Creates and returns a `Cipher` object that uses the given `algorithm` and +`password`. + +The `algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On +recent OpenSSL releases, `openssl list-cipher-algorithms` will display the +available cipher algorithms. + +The `password` is used to derive the cipher key and initialization vector (IV). +The value must be either a `'binary'` encoded string or a [`Buffer`][]. + +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 +password always creates the same key. The low iteration count and +non-cryptographically secure hash algorithm allow passwords to be tested very +rapidly. + +In line with OpenSSL's recommendation to use pbkdf2 instead of +[`EVP_BytesToKey`][] it is recommended that developers derive a key and IV on +their own using [`crypto.pbkdf2()`][] and to use [`crypto.createCipheriv()`][] +to create the `Cipher` object. + +### crypto.createCipheriv(algorithm, key, iv) -## crypto.createDiffieHellman(prime, [prime_encoding], [generator], [generator_encoding]) +Creates and returns a `Cipher` object, with the given `algorithm`, `key` and +initialization vector (`iv`). -Creates a Diffie-Hellman key exchange object using the supplied `prime` and an +The `algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On +recent OpenSSL releases, `openssl list-cipher-algorithms` will 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 `'binary'` encoded strings or +[buffers][`Buffer`]. + +### crypto.createCredentials(details) + + Stability: 0 - Deprecated: Use [`tls.createSecureContext()`][] instead. + +The `crypto.createCredentials()` method is a deprecated alias for creating +and returning a `tls.SecureContext` object. The `crypto.createCredentials()` +method should not be used. + +The optional `details` argument is a hash object with keys: + +* `pfx` : {String|Buffer} - PFX or PKCS12 encoded private + key, certificate and CA certificates +* `key` : {String} - PEM encoded private key +* `passphrase` : {String} - passphrase for the private key or PFX +* `cert` : {String} - PEM encoded certificate +* `ca` : {String|Array} - Either a string or array of strings of PEM encoded CA + certificates to trust. +* `crl` : {String|Array} - Either a string or array of strings of PEM encoded CRLs + (Certificate Revocation List) +* `ciphers`: {String} using the [OpenSSL cipher list format][] describing the + cipher algorithms to use or exclude. + +If no 'ca' details are given, Node.js will use Mozilla's default +[publicly trusted list of CAs][]. + +### crypto.createDecipher(algorithm, password) + +Creates and returns a `Decipher` object that uses the given `algorithm` and +`password` (key). + +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 +password always creates the same key. The low iteration count and +non-cryptographically secure hash algorithm allow passwords to be tested very +rapidly. + +In line with OpenSSL's recommendation to use pbkdf2 instead of +[`EVP_BytesToKey`][] it is recommended that developers derive a key and IV on +their own using [`crypto.pbkdf2()`][] and to use [`crypto.createDecipheriv()`][] +to create the `Decipher` object. + +### crypto.createDecipheriv(algorithm, key, iv) + +Creates and returns a `Decipher` object that uses the given `algorithm`, `key` +and initialization vector (`iv`). + +The `algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On +recent OpenSSL releases, `openssl list-cipher-algorithms` will 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 `'binary'` encoded strings or +[buffers][`Buffer`]. + +### crypto.createDiffieHellman(prime[, prime_encoding][, generator][, generator_encoding]) + +Creates a `DiffieHellman` key exchange object using the supplied `prime` and an optional specific `generator`. -`generator` can be a number, string, or Buffer. -If no `generator` is specified, then `2` is used. -`prime_encoding` and `generator_encoding` can be `'binary'`, `'hex'`, or `'base64'`. -If no `prime_encoding` is specified, then a Buffer is expected for `prime`. -If no `generator_encoding` is specified, then a Buffer is expected for `generator`. -## Class: DiffieHellman +The `generator` argument can be a number, string, or [`Buffer`][]. If +`generator` is not specified, the value `2` is used. -The class for creating Diffie-Hellman key exchanges. +The `prime_encoding` and `generator_encoding` arguments can be `'binary'`, +`'hex'`, or `'base64'`. -Returned by `crypto.createDiffieHellman`. +If `prime_encoding` is specified, `prime` is expected to be a string; otherwise +a [`Buffer`][] is expected. -### diffieHellman.verifyError +If `generator_encoding` is specified, `generator` is expected to be a string; +otherwise either a number or [`Buffer`][] is expected. -A bit field containing any warnings and/or errors as a result of a check performed -during initialization. The following values are valid for this property -(defined in `constants` module): +### crypto.createDiffieHellman(prime_length[, generator]) -* `DH_CHECK_P_NOT_SAFE_PRIME` -* `DH_CHECK_P_NOT_PRIME` -* `DH_UNABLE_TO_CHECK_GENERATOR` -* `DH_NOT_SUITABLE_GENERATOR` +Creates a `DiffieHellman` key exchange object and generates a prime of +`prime_length` bits using an optional specific numeric `generator`. +If `generator` is not specified, the value `2` is used. -### diffieHellman.generateKeys([encoding]) +### crypto.createECDH(curve_name) -Generates private and public Diffie-Hellman key values, and returns -the public key in the specified encoding. This key should be -transferred to the other party. Encoding can be `'binary'`, `'hex'`, -or `'base64'`. If no encoding is provided, then a buffer is returned. +Creates an Elliptic Curve Diffie-Hellman (`ECDH`) key exchange object using a +predefined curve specified by the `curve_name` string. Use +[`crypto.getCurves()`][] to obtain a list of available curve names. On recent +OpenSSL releases, `openssl ecparam -list_curves` will also display the name +and description of each available elliptic curve. -### diffieHellman.computeSecret(other_public_key, [input_encoding], [output_encoding]) +### crypto.createHash(algorithm) -Computes the shared secret using `other_public_key` as the other -party's public key and returns the computed shared secret. Supplied -key is interpreted using specified `input_encoding`, and secret is -encoded using specified `output_encoding`. Encodings can be -`'binary'`, `'hex'`, or `'base64'`. If the input encoding is not -provided, then a buffer is expected. +Creates and returns a `Hash` object that can be used to generate hash digests +using the given `algorithm`. -If no output encoding is given, then a buffer is returned. +The `algorithm` is dependent on the available algorithms supported by the +version of OpenSSL on the platform. Examples are `'sha256'`, `'sha512'`, etc. +On recent releases of OpenSSL, `openssl list-message-digest-algorithms` will +display the available digest algorithms. -### diffieHellman.getPrime([encoding]) +Example: generating the sha256 sum of a file -Returns the Diffie-Hellman prime in the specified encoding, which can -be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided, -then a buffer is returned. +```js +const filename = process.argv[2]; +const crypto = require('crypto'); +const fs = require('fs'); -### diffieHellman.getGenerator([encoding]) +const hash = crypto.createHash('sha256'); -Returns the Diffie-Hellman generator in the specified encoding, which can -be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided, -then a buffer is returned. +const input = fs.createReadStream(filename); +input.on('readable', () => { + var data = input.read(); + if (data) + hash.update(data); + else { + console.log(`${hash.digest('hex')} ${filename}`); + } +}); +``` -### diffieHellman.getPublicKey([encoding]) +### crypto.createHmac(algorithm, key) -Returns the Diffie-Hellman public key in the specified encoding, which -can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided, -then a buffer is returned. +Creates and returns an `Hmac` object that uses the given `algorithm` and `key`. -### diffieHellman.getPrivateKey([encoding]) +The `algorithm` is dependent on the available algorithms supported by the +version of OpenSSL on the platform. Examples are `'sha256'`, `'sha512'`, etc. +On recent releases of OpenSSL, `openssl list-message-digest-algorithms` will +display the available digest algorithms. + +The `key` is the HMAC key used to generate the cryptographic HMAC hash. + +Example: generating the sha256 HMAC of a file -Returns the Diffie-Hellman private key in the specified encoding, -which can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is -provided, then a buffer is returned. +```js +const filename = process.argv[2]; +const crypto = require('crypto'); +const fs = require('fs'); -### diffieHellman.setPublicKey(public_key, [encoding]) +const hmac = crypto.createHmac('sha256', 'a secret'); -Sets the Diffie-Hellman public key. Key encoding can be `'binary'`, -`'hex'` or `'base64'`. If no encoding is provided, then a buffer is -expected. +const input = fs.createReadStream(filename); +input.on('readable', () => { + var data = input.read(); + if (data) + hmac.update(data); + else { + console.log(`${hmac.digest('hex')} ${filename}`); + } +}); +``` -### diffieHellman.setPrivateKey(private_key, [encoding]) +### crypto.createSign(algorithm) + +Creates and returns a `Sign` object that uses the given `algorithm`. On +recent OpenSSL releases, `openssl list-public-key-algorithms` will +display the available signing algorithms. One example is `'RSA-SHA256'`. + +### crypto.createVerify(algorithm) + +Creates and returns a `Verify` object that uses the given algorithm. On +recent OpenSSL releases, `openssl list-public-key-algorithms` will +display the available signing algorithms. One example is `'RSA-SHA256'`. + +### crypto.getCiphers() + +Returns an array with the names of the supported cipher algorithms. + +Example: -Sets the Diffie-Hellman private key. Key encoding can be `'binary'`, -`'hex'` or `'base64'`. If no encoding is provided, then a buffer is -expected. +```js +const ciphers = crypto.getCiphers(); +console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...] +``` -## crypto.getDiffieHellman(group_name) +### crypto.getCurves() -Creates a predefined Diffie-Hellman key exchange object. The -supported groups are: `'modp1'`, `'modp2'`, `'modp5'` (defined in [RFC -2412][]) and `'modp14'`, `'modp15'`, `'modp16'`, `'modp17'`, -`'modp18'` (defined in [RFC 3526][]). The returned object mimics the -interface of objects created by [crypto.createDiffieHellman()][] -above, but will not allow to change the keys (with -[diffieHellman.setPublicKey()][] for example). The advantage of using -this routine is that the parties don't have to generate nor exchange -group modulus beforehand, saving both processor and communication -time. +Returns an array with the names of the supported elliptic curves. + +Example: + +```js +const curves = crypto.getCurves(); +console.log(curves); // ['secp256k1', 'secp384r1', ...] +``` + +### crypto.getDiffieHellman(group_name) + +Creates a predefined `DiffieHellman` key exchange object. The +supported groups are: `'modp1'`, `'modp2'`, `'modp5'` (defined in +[RFC 2412][], but see [Caveats][]) and `'modp14'`, `'modp15'`, +`'modp16'`, `'modp17'`, `'modp18'` (defined in [RFC 3526][]). The +returned object mimics the interface of objects created by +[`crypto.createDiffieHellman()`][], but will not allow changing +the keys (with [`diffieHellman.setPublicKey()`][] for example). The +advantage of using this method is that the parties do not have to +generate nor exchange a group modulus beforehand, saving both processor +and communication time. Example (obtaining a shared secret): - var crypto = require('crypto'); - var alice = crypto.getDiffieHellman('modp5'); - var bob = crypto.getDiffieHellman('modp5'); +```js +const crypto = require('crypto'); +const alice = crypto.getDiffieHellman('modp14'); +const bob = crypto.getDiffieHellman('modp14'); - alice.generateKeys(); - bob.generateKeys(); +alice.generateKeys(); +bob.generateKeys(); - var alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); - var bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); +const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); +const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); - /* alice_secret and bob_secret should be the same */ - console.log(alice_secret == bob_secret); +/* alice_secret and bob_secret should be the same */ +console.log(alice_secret == bob_secret); +``` -## crypto.pbkdf2(password, salt, iterations, keylen, [digest], callback) +### crypto.getHashes() -Asynchronous PBKDF2 function. Applies the selected HMAC digest function -(default: SHA1) to derive a key of the requested length from the password, -salt and number of iterations. The callback gets two arguments: -`(err, derivedKey)`. +Returns an array with the names of the supported hash algorithms. Example: - crypto.pbkdf2('secret', 'salt', 4096, 512, 'sha256', function(err, key) { - if (err) - throw err; - console.log(key.toString('hex')); // 'c5e478d...1469e50' - }); +```js +const hashes = crypto.getHashes(); +console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...] +``` + +### crypto.pbkdf2(password, salt, iterations, keylen[, digest], callback) -You can get a list of supported digest functions with -[crypto.getHashes()](#crypto_crypto_gethashes). +Provides an asynchronous Password-Based Key Derivation Function 2 (PBKDF2) +implementation. A selected HMAC digest algorithm specified by `digest` is +applied to derive a key of the requested byte length (`keylen`) from the +`password`, `salt` and `iterations`. If the `digest` algorithm is not specified, +a default of `'sha1'` is used. -## crypto.pbkdf2Sync(password, salt, iterations, keylen, [digest]) +The supplied `callback` function is called with two arguments: `err` and +`derivedKey`. If an error occurs, `err` will be set; otherwise `err` will be +null. The successfully generated `derivedKey` will be passed as a [`Buffer`][]. -Synchronous PBKDF2 function. Returns derivedKey or throws error. +The `iterations` argument must be a number set as high as possible. The +higher the number of iterations, the more secure the derived key will be, +but will take a longer amount of time to complete. -## crypto.randomBytes(size, [callback]) +The `salt` should also be as unique as possible. It is recommended that the +salts are random and their lengths are greater than 16 bytes. See +[NIST SP 800-132][] for details. -Generates cryptographically strong pseudo-random data. Usage: +Example: - // async - crypto.randomBytes(256, function(ex, buf) { - if (ex) throw ex; - console.log('Have %d bytes of random data: %s', buf.length, buf); - }); +```js +const crypto = require('crypto'); +crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, key) => { + if (err) throw err; + console.log(key.toString('hex')); // 'c5e478d...1469e50' +}); +``` - // sync - try { - var buf = crypto.randomBytes(256); - console.log('Have %d bytes of random data: %s', buf.length, buf); - } catch (ex) { - // handle error - // most likely, entropy sources are drained - } +An array of supported digest functions can be retrieved using +[`crypto.getHashes()`][]. -NOTE: Will throw error or invoke callback with error, if there is not enough -accumulated entropy to generate cryptographically strong data. In other words, -`crypto.randomBytes` without callback will not block even if all entropy sources -are drained. +### crypto.pbkdf2Sync(password, salt, iterations, keylen[, digest]) -## crypto.pseudoRandomBytes(size, [callback]) +Provides a synchronous Password-Based Key Derivation Function 2 (PBKDF2) +implementation. A selected HMAC digest algorithm specified by `digest` is +applied to derive a key of the requested byte length (`keylen`) from the +`password`, `salt` and `iterations`. If the `digest` algorithm is not specified, +a default of `'sha1'` is used. -Generates *non*-cryptographically strong pseudo-random data. The data -returned will be unique if it is sufficiently long, but is not -necessarily unpredictable. For this reason, the output of this -function should never be used where unpredictability is important, -such as in the generation of encryption keys. +If an error occurs an Error will be thrown, otherwise the derived key will be +returned as a [`Buffer`][]. -Usage is otherwise identical to `crypto.randomBytes`. +The `iterations` argument must be a number set as high as possible. The +higher the number of iterations, the more secure the derived key will be, +but will take a longer amount of time to complete. -## Class: Certificate +The `salt` should also be as unique as possible. It is recommended that the +salts are random and their lengths are greater than 16 bytes. See +[NIST SP 800-132][] for details. -The class used for working with signed public key & challenges. The most -common usage for this series of functions is when dealing with the `` -element. http://www.openssl.org/docs/apps/spkac.html +Example: -Returned by `crypto.Certificate`. +```js +const crypto = require('crypto'); +const key = crypto.pbkdf2Sync('secret', 'salt', 100000, 512, 'sha512'); +console.log(key.toString('hex')); // 'c5e478d...1469e50' +``` -### Certificate.verifySpkac(spkac) +An array of supported digest functions can be retrieved using +[`crypto.getHashes()`][]. -Returns true of false based on the validity of the SPKAC. +### crypto.privateDecrypt(private_key, buffer) -### Certificate.exportChallenge(spkac) +Decrypts `buffer` with `private_key`. -Exports the encoded public key from the supplied SPKAC. +`private_key` can be an object or a string. If `private_key` is a string, it is +treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`. +If `private_key` is an object, it is interpreted as a hash object with the +keys: -### Certificate.exportPublicKey(spkac) +* `key` : {String} - PEM encoded private key +* `passphrase` : {String} - Optional passphrase for the private key +* `padding` : An optional padding value, one of the following: + * `constants.RSA_NO_PADDING` + * `constants.RSA_PKCS1_PADDING` + * `constants.RSA_PKCS1_OAEP_PADDING` -Exports the encoded challenge associated with the SPKAC. +All paddings are defined in the `constants` module. -## crypto.DEFAULT_ENCODING +### crypto.privateEncrypt(private_key, buffer) -The default encoding to use for functions that can take either strings -or buffers. The default value is `'buffer'`, which makes it default -to using Buffer objects. This is here to make the crypto module more -easily compatible with legacy programs that expected `'binary'` to be -the default encoding. - -Note that new programs will probably expect buffers, so only use this -as a temporary measure. - -## Recent API Changes - -The Crypto module was added to Node before there was the concept of a -unified Stream API, and before there were Buffer objects for handling -binary data. - -As such, the streaming classes don't have the typical methods found on -other Node classes, and many methods accepted and returned -Binary-encoded strings by default rather than Buffers. This was -changed to use Buffers by default instead. - -This is a breaking change for some use cases, but not all. - -For example, if you currently use the default arguments to the Sign -class, and then pass the results to the Verify class, without ever -inspecting the data, then it will continue to work as before. Where -you once got a binary string and then presented the binary string to -the Verify object, you'll now get a Buffer, and present the Buffer to -the Verify object. - -However, if you were doing things with the string data that will not -work properly on Buffers (such as, concatenating them, storing in -databases, etc.), or you are passing binary strings to the crypto -functions without an encoding argument, then you will need to start -providing encoding arguments to specify which encoding you'd like to -use. To switch to the previous style of using binary strings by -default, set the `crypto.DEFAULT_ENCODING` field to 'binary'. Note -that new programs will probably expect buffers, so only use this as a -temporary measure. - - -[createCipher()]: #crypto_crypto_createcipher_algorithm_password -[createCipheriv()]: #crypto_crypto_createcipheriv_algorithm_key_iv -[crypto.createDiffieHellman()]: #crypto_crypto_creatediffiehellman_prime_encoding -[diffieHellman.setPublicKey()]: #crypto_diffiehellman_setpublickey_public_key_encoding -[RFC 2412]: http://www.rfc-editor.org/rfc/rfc2412.txt -[RFC 3526]: http://www.rfc-editor.org/rfc/rfc3526.txt +Encrypts `buffer` with `private_key`. + +`private_key` can be an object or a string. If `private_key` is a string, it is +treated as the key with no passphrase and will use `RSA_PKCS1_PADDING`. +If `private_key` is an object, it is interpreted as a hash object with the +keys: + +* `key` : {String} - PEM encoded private key +* `passphrase` : {String} - Optional passphrase for the private key +* `padding` : An optional padding value, one of the following: + * `constants.RSA_NO_PADDING` + * `constants.RSA_PKCS1_PADDING` + * `constants.RSA_PKCS1_OAEP_PADDING` + +All paddings are defined in the `constants` module. + +### crypto.publicDecrypt(public_key, buffer) + +Decrypts `buffer` with `public_key`. + +`public_key` can be an object or a string. If `public_key` is a string, it is +treated as the key with no passphrase and will use `RSA_PKCS1_PADDING`. +If `public_key` is an object, it is interpreted as a hash object with the +keys: + +* `key` : {String} - PEM encoded public key +* `passphrase` : {String} - Optional passphrase for the private key +* `padding` : An optional padding value, one of the following: + * `constants.RSA_NO_PADDING` + * `constants.RSA_PKCS1_PADDING` + * `constants.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. + +All paddings are defined in the `constants` module. + +### crypto.publicEncrypt(public_key, buffer) + +Encrypts `buffer` with `public_key`. + +`public_key` can be an object or a string. If `public_key` is a string, it is +treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`. +If `public_key` is an object, it is interpreted as a hash object with the +keys: + +* `key` : {String} - PEM encoded public key +* `passphrase` : {String} - Optional passphrase for the private key +* `padding` : An optional padding value, one of the following: + * `constants.RSA_NO_PADDING` + * `constants.RSA_PKCS1_PADDING` + * `constants.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. + +All paddings are defined in the `constants` module. + +### crypto.randomBytes(size[, callback]) + +Generates cryptographically strong pseudo-random data. The `size` argument +is a number indicating the number of bytes to generate. + +If a `callback` function is provided, the bytes are generated asynchronously +and the `callback` function is invoked with two arguments: `err` and `buf`. +If an error occurs, `err` will be an Error object; otherwise it is null. The +`buf` argument is a [`Buffer`][] containing the generated bytes. + +```js +// Asynchronous +const crypto = require('crypto'); +crypto.randomBytes(256, (err, buf) => { + if (err) throw err; + console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`); +}); +``` + +If the `callback` function is not provided, the random bytes are generated +synchronously and returned as a [`Buffer`][]. An error will be thrown if +there is a problem generating the bytes. + +```js +// Synchronous +const buf = crypto.randomBytes(256); +console.log( + `${buf.length} bytes of random data: ${buf.toString('hex')}`); +``` + +The `crypto.randomBytes()` method will block until there is sufficient entropy. +This should normally never take longer than a few milliseconds. The only time +when generating the random bytes may conceivably block for a longer period of +time is right after boot, when the whole system is still low on entropy. + +### crypto.setEngine(engine[, flags]) + +Load and set the `engine` for some or all OpenSSL functions (selected by flags). + +`engine` could be either an id or a path to the engine's shared library. + +The optional `flags` argument uses `ENGINE_METHOD_ALL` by default. The `flags` +is a bit field taking one of or a mix of the following flags (defined in the +`constants` module): + +* `ENGINE_METHOD_RSA` +* `ENGINE_METHOD_DSA` +* `ENGINE_METHOD_DH` +* `ENGINE_METHOD_RAND` +* `ENGINE_METHOD_ECDH` +* `ENGINE_METHOD_ECDSA` +* `ENGINE_METHOD_CIPHERS` +* `ENGINE_METHOD_DIGESTS` +* `ENGINE_METHOD_STORE` +* `ENGINE_METHOD_PKEY_METH` +* `ENGINE_METHOD_PKEY_ASN1_METH` +* `ENGINE_METHOD_ALL` +* `ENGINE_METHOD_NONE` + +## Notes + +### Legacy Streams API (pre Node.js v0.10) + +The Crypto module was added to Node.js before there was the concept of a +unified Stream API, and before there were [`Buffer`][] objects for handling +binary data. As such, the many of the `crypto` defined classes have methods not +typically found on other Node.js classes that implement the [streams][stream] +API (e.g. `update()`, `final()`, or `digest()`). Also, many methods accepted +and returned `'binary'` encoded strings by default rather than Buffers. This +default was changed after Node.js v0.8 to use [`Buffer`][] objects by default +instead. + +### Recent ECDH Changes + +Usage of `ECDH` with non-dynamically generated key pairs has been simplified. +Now, [`ecdh.setPrivateKey()`][] can be called with a preselected private key +and the associated public point (key) will be computed and stored in the object. +This allows code to only store and provide the private part of the EC key pair. +[`ecdh.setPrivateKey()`][] now also validates that the private key is valid for +the selected curve. + +The [`ecdh.setPublicKey()`][] method is now deprecated as its inclusion in the +API is not useful. Either a previously stored private key should be set, which +automatically generates the associated public key, or [`ecdh.generateKeys()`][] +should be called. The main drawback of using [`ecdh.setPublicKey()`][] is that +it can be used to put the ECDH key pair into an inconsistent state. + +### Support for weak or compromised algorithms + +The `crypto` module still supports some algorithms which are already +compromised and are not currently recommended for use. The API also allows +the use of ciphers and hashes with a small key size that are considered to be +too weak for safe use. + +Users should take full responsibility for selecting the crypto +algorithm and key size according to their security requirements. + +Based on the recommendations of [NIST SP 800-131A][]: + +- MD5 and SHA-1 are no longer acceptable where collision resistance is + required such as digital signatures. +- The key used with RSA, DSA and DH algorithms is recommended to have + at least 2048 bits and that of the curve of ECDSA and ECDH at least + 224 bits, to be safe to use for several years. +- The DH groups of `modp1`, `modp2` and `modp5` have a key size + smaller than 2048 bits and are not recommended. + +See the reference for other recommendations and details. + +[`Buffer`]: buffer.html +[`cipher.final()`]: #crypto_cipher_final_output_encoding +[`cipher.update()`]: #crypto_cipher_update_data_input_encoding_output_encoding +[`crypto.createCipher()`]: #crypto_crypto_createcipher_algorithm_password +[`crypto.createCipheriv()`]: #crypto_crypto_createcipheriv_algorithm_key_iv +[`crypto.createDecipher()`]: #crypto_crypto_createdecipher_algorithm_password +[`crypto.createDecipheriv()`]: #crypto_crypto_createdecipheriv_algorithm_key_iv +[`crypto.createDiffieHellman()`]: #crypto_crypto_creatediffiehellman_prime_prime_encoding_generator_generator_encoding +[`crypto.createECDH()`]: #crypto_crypto_createecdh_curve_name +[`crypto.createHash()`]: #crypto_crypto_createhash_algorithm +[`crypto.createHmac()`]: #crypto_crypto_createhmac_algorithm_key +[`crypto.createSign()`]: #crypto_crypto_createsign_algorithm +[`crypto.getCurves()`]: #crypto_crypto_getcurves +[`crypto.getHashes()`]: #crypto_crypto_gethashes +[`crypto.pbkdf2()`]: #crypto_crypto_pbkdf2_password_salt_iterations_keylen_digest_callback +[`decipher.final()`]: #crypto_decipher_final_output_encoding +[`decipher.update()`]: #crypto_decipher_update_data_input_encoding_output_encoding +[`diffieHellman.setPublicKey()`]: #crypto_diffiehellman_setpublickey_public_key_encoding +[`ecdh.generateKeys()`]: #crypto_ecdh_generatekeys_encoding_format +[`ecdh.setPrivateKey()`]: #crypto_ecdh_setprivatekey_private_key_encoding +[`ecdh.setPublicKey()`]: #crypto_ecdh_setpublickey_public_key_encoding +[`EVP_BytesToKey`]: https://www.openssl.org/docs/crypto/EVP_BytesToKey.html +[`hash.digest()`]: #crypto_hash_digest_encoding +[`hash.update()`]: #crypto_hash_update_data_input_encoding +[`hmac.digest()`]: #crypto_hmac_digest_encoding +[`hmac.update()`]: #crypto_hmac_update_data +[`sign.sign()`]: #crypto_sign_sign_private_key_output_format +[`sign.update()`]: #crypto_sign_update_data +[`tls.createSecureContext()`]: tls.html#tls_tls_createsecurecontext_details +[`verify.update()`]: #crypto_verifier_update_data +[`verify.verify()`]: #crypto_verifier_verify_object_signature_signature_format +[Caveats]: #crypto_support_for_weak_or_compromised_algorithms +[HTML5's `keygen` element]: http://www.w3.org/TR/html5/forms.html#the-keygen-element +[initialization vector]: https://en.wikipedia.org/wiki/Initialization_vector +[NIST SP 800-131A]: http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf +[NIST SP 800-132]: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf +[OpenSSL cipher list format]: https://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT +[OpenSSL's SPKAC implementation]: https://www.openssl.org/docs/apps/spkac.html +[publicly trusted list of CAs]: https://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt +[RFC 2412]: https://www.rfc-editor.org/rfc/rfc2412.txt +[RFC 3526]: https://www.rfc-editor.org/rfc/rfc3526.txt +[stream]: stream.html +[stream-writable-write]: stream.html#stream_writable_write_chunk_encoding_callback