diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown index dea78df8f7f91b..d10098feb7a423 100644 --- a/doc/api/crypto.markdown +++ b/doc/api/crypto.markdown @@ -1062,13 +1062,12 @@ const hashes = crypto.getHashes(); console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...] ``` -### crypto.pbkdf2(password, salt, iterations, keylen[, digest], callback) +### crypto.pbkdf2(password, salt, iterations, keylen, digest, callback) 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. +`password`, `salt` and `iterations`. The supplied `callback` function is called with two arguments: `err` and `derivedKey`. If an error occurs, `err` will be set; otherwise `err` will be @@ -1095,13 +1094,12 @@ crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, key) => { An array of supported digest functions can be retrieved using [`crypto.getHashes()`][]. -### crypto.pbkdf2Sync(password, salt, iterations, keylen[, digest]) +### crypto.pbkdf2Sync(password, salt, iterations, keylen, digest) 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. +`password`, `salt` and `iterations`. If an error occurs an Error will be thrown, otherwise the derived key will be returned as a [`Buffer`][]. diff --git a/lib/crypto.js b/lib/crypto.js index bed7d7764e3ad5..4b0539406e5ac6 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -531,6 +531,11 @@ ECDH.prototype.getPublicKey = function getPublicKey(encoding, format) { }; +const pbkdf2DeprecationWarning = + internalUtil.deprecate(() => {}, 'crypto.pbkdf2 without specifying' + + ' a digest is deprecated. Please specify a digest'); + + exports.pbkdf2 = function(password, salt, iterations, @@ -540,6 +545,7 @@ exports.pbkdf2 = function(password, if (typeof digest === 'function') { callback = digest; digest = undefined; + pbkdf2DeprecationWarning(); } if (typeof callback !== 'function') @@ -550,6 +556,10 @@ exports.pbkdf2 = function(password, exports.pbkdf2Sync = function(password, salt, iterations, keylen, digest) { + if (typeof digest === 'undefined') { + digest = undefined; + pbkdf2DeprecationWarning(); + } return pbkdf2(password, salt, iterations, keylen, digest); }; diff --git a/test/parallel/test-crypto-binary-default.js b/test/parallel/test-crypto-binary-default.js index c4b8990beb2ec2..1ce64a40c8ed0d 100644 --- a/test/parallel/test-crypto-binary-default.js +++ b/test/parallel/test-crypto-binary-default.js @@ -633,34 +633,34 @@ assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); // Test PBKDF2 with RFC 6070 test vectors (except #4) // function testPBKDF2(password, salt, iterations, keylen, expected) { - var actual = crypto.pbkdf2Sync(password, salt, iterations, keylen); + var actual = crypto.pbkdf2Sync(password, salt, iterations, keylen, 'sha256'); assert.equal(actual, expected); - crypto.pbkdf2(password, salt, iterations, keylen, function(err, actual) { + crypto.pbkdf2(password, salt, iterations, keylen, 'sha256', (err, actual) => { assert.equal(actual, expected); }); } testPBKDF2('password', 'salt', 1, 20, - '\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24' + - '\xaf\x60\x12\x06\x2f\xe0\x37\xa6'); + '\x12\x0f\xb6\xcf\xfc\xf8\xb3\x2c\x43\xe7\x22\x52' + + '\x56\xc4\xf8\x37\xa8\x65\x48\xc9'); testPBKDF2('password', 'salt', 2, 20, - '\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a' + - '\xce\x1d\x41\xf0\xd8\xde\x89\x57'); + '\xae\x4d\x0c\x95\xaf\x6b\x46\xd3\x2d\x0a\xdf\xf9' + + '\x28\xf0\x6d\xd0\x2a\x30\x3f\x8e'); testPBKDF2('password', 'salt', 4096, 20, - '\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26' + - '\xf7\x21\xd0\x65\xa4\x29\xc1'); + '\xc5\xe4\x78\xd5\x92\x88\xc8\x41\xaa\x53\x0d\xb6' + + '\x84\x5c\x4c\x8d\x96\x28\x93\xa0'); testPBKDF2('passwordPASSWORDpassword', 'saltSALTsaltSALTsaltSALTsaltSALTsalt', 4096, 25, - '\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62' + - '\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38'); + '\x34\x8c\x89\xdb\xcb\xd3\x2b\x2f\x32\xd8\x14\xb8' + + '\x11\x6e\x84\xcf\x2b\x17\x34\x7e\xbc\x18\x00\x18\x1c'); testPBKDF2('pass\0word', 'sa\0lt', 4096, 16, - '\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34' + - '\x25\xe0\xc3'); + '\x89\xb6\x9d\x05\x16\xf8\x29\x89\x3c\x69\x62\x26' + + '\x65\x0a\x86\x87'); diff --git a/test/parallel/test-crypto-pbkdf2.js b/test/parallel/test-crypto-pbkdf2.js index 39b98b38e2710e..cbea3dae4c0d04 100644 --- a/test/parallel/test-crypto-pbkdf2.js +++ b/test/parallel/test-crypto-pbkdf2.js @@ -12,37 +12,37 @@ var crypto = require('crypto'); // Test PBKDF2 with RFC 6070 test vectors (except #4) // function testPBKDF2(password, salt, iterations, keylen, expected) { - var actual = crypto.pbkdf2Sync(password, salt, iterations, keylen); + var actual = crypto.pbkdf2Sync(password, salt, iterations, keylen, 'sha256'); assert.equal(actual.toString('binary'), expected); - crypto.pbkdf2(password, salt, iterations, keylen, function(err, actual) { + crypto.pbkdf2(password, salt, iterations, keylen, 'sha256', (err, actual) => { assert.equal(actual.toString('binary'), expected); }); } testPBKDF2('password', 'salt', 1, 20, - '\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24' + - '\xaf\x60\x12\x06\x2f\xe0\x37\xa6'); + '\x12\x0f\xb6\xcf\xfc\xf8\xb3\x2c\x43\xe7\x22\x52' + + '\x56\xc4\xf8\x37\xa8\x65\x48\xc9'); testPBKDF2('password', 'salt', 2, 20, - '\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a' + - '\xce\x1d\x41\xf0\xd8\xde\x89\x57'); + '\xae\x4d\x0c\x95\xaf\x6b\x46\xd3\x2d\x0a\xdf\xf9' + + '\x28\xf0\x6d\xd0\x2a\x30\x3f\x8e'); testPBKDF2('password', 'salt', 4096, 20, - '\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26' + - '\xf7\x21\xd0\x65\xa4\x29\xc1'); + '\xc5\xe4\x78\xd5\x92\x88\xc8\x41\xaa\x53\x0d\xb6' + + '\x84\x5c\x4c\x8d\x96\x28\x93\xa0'); testPBKDF2('passwordPASSWORDpassword', 'saltSALTsaltSALTsaltSALTsaltSALTsalt', 4096, 25, - '\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62' + - '\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38'); + '\x34\x8c\x89\xdb\xcb\xd3\x2b\x2f\x32\xd8\x14\xb8\x11' + + '\x6e\x84\xcf\x2b\x17\x34\x7e\xbc\x18\x00\x18\x1c'); testPBKDF2('pass\0word', 'sa\0lt', 4096, 16, - '\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34' + - '\x25\xe0\xc3'); + '\x89\xb6\x9d\x05\x16\xf8\x29\x89\x3c\x69\x62\x26\x65' + + '\x0a\x86\x87'); var expected = '64c486c55d30d4c5a079b8823b7d7cb37ff0556f537da8410233bcec330ed956'; @@ -62,28 +62,28 @@ assert.throws(function() { // Should not work with Infinity key length assert.throws(function() { - crypto.pbkdf2('password', 'salt', 1, Infinity, common.fail); + crypto.pbkdf2('password', 'salt', 1, Infinity, 'sha256', common.fail); }, function(err) { return err instanceof Error && err.message === 'Bad key length'; }); // Should not work with negative Infinity key length assert.throws(function() { - crypto.pbkdf2('password', 'salt', 1, -Infinity, common.fail); + crypto.pbkdf2('password', 'salt', 1, -Infinity, 'sha256', common.fail); }, function(err) { return err instanceof Error && err.message === 'Bad key length'; }); // Should not work with NaN key length assert.throws(function() { - crypto.pbkdf2('password', 'salt', 1, NaN, common.fail); + crypto.pbkdf2('password', 'salt', 1, NaN, 'sha256', common.fail); }, function(err) { return err instanceof Error && err.message === 'Bad key length'; }); // Should not work with negative key length assert.throws(function() { - crypto.pbkdf2('password', 'salt', 1, -1, common.fail); + crypto.pbkdf2('password', 'salt', 1, -1, 'sha256', common.fail); }, function(err) { return err instanceof Error && err.message === 'Bad key length'; });