Skip to content

Commit

Permalink
crypto: pbkdf2 deprecate digest overload.
Browse files Browse the repository at this point in the history
As per #3292, this PR introduces a deprecation notice about removing
the 'default digest' overload which currently defaults to the soon
to be defunct SHA1 digest.

Instead it should be left up to the documentation and implementor to
suggest a suitable digest function.

Ref: #3292
PR-URL: #4047
Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
  • Loading branch information
tomgco authored and Shigeki Ohtsu committed Jan 22, 2016
1 parent db9e122 commit a116358
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 34 deletions.
10 changes: 4 additions & 6 deletions doc/api/crypto.markdown
Expand Up @@ -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
Expand All @@ -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`][].
Expand Down
10 changes: 10 additions & 0 deletions lib/crypto.js
Expand Up @@ -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,
Expand All @@ -540,6 +545,7 @@ exports.pbkdf2 = function(password,
if (typeof digest === 'function') {
callback = digest;
digest = undefined;
pbkdf2DeprecationWarning();
}

if (typeof callback !== 'function')
Expand All @@ -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);
};

Expand Down
24 changes: 12 additions & 12 deletions test/parallel/test-crypto-binary-default.js
Expand Up @@ -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');
32 changes: 16 additions & 16 deletions test/parallel/test-crypto-pbkdf2.js
Expand Up @@ -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';
Expand All @@ -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';
});

0 comments on commit a116358

Please sign in to comment.