-
-
Notifications
You must be signed in to change notification settings - Fork 902
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: remove insecure fallback random number generator
BREAKING CHANGE: Remove builtin support for insecure random number generators in the browser. Users who want that will have to supply their own random number generator function. Fixes #173.
- Loading branch information
Showing
8 changed files
with
96 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,21 @@ | ||
// Unique ID creation requires a high quality random # generator. In the | ||
// browser this is a little complicated due to unknown quality of Math.random() | ||
// and inconsistent support for the `crypto` API. We do the best we can via | ||
// feature-detection | ||
// Unique ID creation requires a high quality random # generator. In the browser we therefore | ||
// require the crypto API and do not support built-in fallback to lower quality random number | ||
// generators (like Math.random()). | ||
|
||
// getRandomValues needs to be invoked in a context where "this" is a Crypto | ||
// implementation. Also, find the complete implementation of crypto on IE11. | ||
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also, | ||
// find the complete implementation of crypto (msCrypto) on IE11. | ||
var getRandomValues = | ||
(typeof crypto != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || | ||
(typeof msCrypto != 'undefined' && | ||
typeof window.msCrypto.getRandomValues == 'function' && | ||
msCrypto.getRandomValues.bind(msCrypto)); | ||
|
||
let rng; | ||
|
||
if (getRandomValues) { | ||
// WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto | ||
var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef | ||
|
||
rng = function whatwgRNG() { | ||
getRandomValues(rnds8); | ||
return rnds8; | ||
}; | ||
} else { | ||
// Math.random()-based (RNG) | ||
// | ||
// If all else fails, use Math.random(). It's fast, but is of unspecified | ||
// quality. | ||
var rnds = new Array(16); | ||
|
||
rng = function mathRNG() { | ||
for (var i = 0, r; i < 16; i++) { | ||
if ((i & 0x03) === 0) r = Math.random() * 0x100000000; | ||
rnds[i] = (r >>> ((i & 0x03) << 3)) & 0xff; | ||
} | ||
|
||
return rnds; | ||
}; | ||
var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef | ||
export default function rng() { | ||
if (!getRandomValues) { | ||
throw new Error( | ||
'uuid: This browser does not seem to support crypto.getRandomValues(). If you need to support this browser, please provide a custom random number generator through options.rng.', | ||
); | ||
} | ||
return getRandomValues(rnds8); | ||
} | ||
|
||
export default rng; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import crypto from 'crypto'; | ||
|
||
export default function nodeRNG() { | ||
export default function rng() { | ||
return crypto.randomBytes(16); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import assert from 'assert'; | ||
import v1 from '../../src/v1.js'; | ||
|
||
// Since the clockseq is cached in the module this test must run in a separate file in order to | ||
// initialize the v1 clockseq with controlled random data. | ||
describe('v1', () => { | ||
const randomBytesFixture = [ | ||
0x10, | ||
0x91, | ||
0x56, | ||
0xbe, | ||
0xc4, | ||
0xfb, | ||
0xc1, | ||
0xea, | ||
0x71, | ||
0xb4, | ||
0xef, | ||
0xe1, | ||
0x67, | ||
0x1c, | ||
0x58, | ||
0x36, | ||
]; | ||
|
||
test('explicit options.random produces expected id', () => { | ||
const id = v1({ | ||
msecs: 1321651533573, | ||
nsecs: 5432, | ||
random: randomBytesFixture, | ||
}); | ||
assert.strictEqual(id, 'd9428888-122b-11e1-81ea-119156bec4fb'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import assert from 'assert'; | ||
import v1 from '../../src/v1.js'; | ||
|
||
// Since the clockseq is cached in the module this test must run in a separate file in order to | ||
// initialize the v1 clockseq with controlled random data. | ||
describe('v1', () => { | ||
const randomBytesFixture = [ | ||
0x10, | ||
0x91, | ||
0x56, | ||
0xbe, | ||
0xc4, | ||
0xfb, | ||
0xc1, | ||
0xea, | ||
0x71, | ||
0xb4, | ||
0xef, | ||
0xe1, | ||
0x67, | ||
0x1c, | ||
0x58, | ||
0x36, | ||
]; | ||
|
||
test('explicit options.random produces expected id', () => { | ||
const id = v1({ | ||
msecs: 1321651533573, | ||
nsecs: 5432, | ||
rng: () => randomBytesFixture, | ||
}); | ||
assert.strictEqual(id, 'd9428888-122b-11e1-81ea-119156bec4fb'); | ||
}); | ||
}); |