|
1 |
| -/*globals window, global*/ |
| 1 | +/*globals window, global, require*/ |
2 | 2 |
|
3 | 3 | /**
|
4 | 4 | * CryptoJS core components.
|
5 | 5 | */
|
6 | 6 | var CryptoJS = CryptoJS || (function (Math, undefined) {
|
7 | 7 |
|
| 8 | + var crypto; |
| 9 | + |
| 10 | + // Native crypto from window (Browser) |
| 11 | + if (typeof window !== 'undefined' && window.crypto) { |
| 12 | + crypto = window.crypto; |
| 13 | + } |
| 14 | + |
| 15 | + // Native (experimental IE 11) crypto from window (Browser) |
| 16 | + if (!crypto && typeof window !== 'undefined' && window.msCrypto) { |
| 17 | + crypto = window.msCrypto; |
| 18 | + } |
| 19 | + |
| 20 | + // Native crypto from global (NodeJS) |
| 21 | + if (!crypto && typeof global !== 'undefined' && global.crypto) { |
| 22 | + crypto = global.crypto; |
| 23 | + } |
| 24 | + |
| 25 | + // Native crypto import via require (NodeJS) |
| 26 | + if (!crypto && typeof require === 'function') { |
| 27 | + try { |
| 28 | + crypto = require('crypto'); |
| 29 | + } catch (err) {} |
| 30 | + } |
| 31 | + |
8 | 32 | /*
|
9 | 33 | * Cryptographically secure pseudorandom number generator
|
10 | 34 | *
|
11 | 35 | * As Math.random() is cryptographically not safe to use
|
12 | 36 | */
|
13 |
| - var secureRandom = function () { |
14 |
| - // Native crypto module on NodeJS environment |
15 |
| - try { |
16 |
| - // Crypto from global object |
17 |
| - var crypto = global.crypto; |
18 |
| - |
19 |
| - // Create a random float number between 0 and 1 |
20 |
| - return Number('0.' + crypto.randomBytes(3).readUIntBE(0, 3)); |
21 |
| - } catch (err) {} |
22 |
| - |
23 |
| - // Native crypto module in Browser environment |
24 |
| - try { |
25 |
| - // Support experimental crypto module in IE 11 |
26 |
| - var crypto = window.crypto || window.msCrypto; |
| 37 | + var cryptoSecureRandomInt = function () { |
| 38 | + if (crypto) { |
| 39 | + // Use getRandomValues method (Browser) |
| 40 | + if (typeof crypto.getRandomValues === 'function') { |
| 41 | + try { |
| 42 | + return crypto.getRandomValues(new Uint32Array(1))[0]; |
| 43 | + } catch (err) {} |
| 44 | + } |
27 | 45 |
|
28 |
| - // Create a random float number between 0 and 1 |
29 |
| - return Number('0.' + window.crypto.getRandomValues(new Uint32Array(1))[0]); |
30 |
| - } catch (err) {} |
| 46 | + // Use randomBytes method (NodeJS) |
| 47 | + if (typeof crypto.randomBytes === 'function') { |
| 48 | + try { |
| 49 | + return crypto.randomBytes(4).readInt32LE(); |
| 50 | + } catch (err) {} |
| 51 | + } |
| 52 | + } |
31 | 53 |
|
32 | 54 | throw new Error('Native crypto module could not be used to get secure random number.');
|
33 | 55 | };
|
@@ -321,7 +343,7 @@ var CryptoJS = CryptoJS || (function (Math, undefined) {
|
321 | 343 | var words = [];
|
322 | 344 |
|
323 | 345 | for (var i = 0; i < nBytes; i += 4) {
|
324 |
| - words.push((secureRandom() * 0x100000000) | 0); |
| 346 | + words.push(cryptoSecureRandomInt()); |
325 | 347 | }
|
326 | 348 |
|
327 | 349 | return new WordArray.init(words, nBytes);
|
|
0 commit comments