diff --git a/README.md b/README.md index bccfad7..93d9477 100644 --- a/README.md +++ b/README.md @@ -208,3 +208,28 @@ console.log(decryptedData); // [{id: 1}, {id: 2}] - ```crypto-js/pad-iso97971``` - ```crypto-js/pad-zeropadding``` - ```crypto-js/pad-nopadding``` + + +## Release notes + +### 3.2.1 + +The usage of the native crypto module has been fixed. The import and access of the native crypto module has been improved. + +### 3.2.0 + +In this version `Math.random()` has been replaced by the random methods of the native crypto module. + +For this reason CryptoJS might does not run in some JavaScript environments without native crypto module. Such as IE 10 or before. + +If it's absolute required to run CryptoJS in such an environment, stay with `3.1.x` version. Encrypting and decrypting stays compatible. But keep in mind `3.1.x` versions still use `Math.random()` which is cryptographically not secure, as it's not random enough. + +This version came along with `CRITICAL` `BUG`. + +DO NOT USE THIS VERSION! Please, go for a newer version! + +### 3.1.x + +The `3.1.x` are based on the original CryptoJS, wrapped in CommonJS modules. + + diff --git a/bower.json b/bower.json index 795718f..78cab30 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "crypto-js", - "version": "3.2.0", + "version": "3.2.1", "description": "JavaScript library of crypto standards.", "license": "MIT", "homepage": "http://github.com/brix/crypto-js", diff --git a/core.js b/core.js index dac4ccb..0ef552b 100644 --- a/core.js +++ b/core.js @@ -13,34 +13,58 @@ } }(this, function () { + /*globals window, global, require*/ + /** * CryptoJS core components. */ var CryptoJS = CryptoJS || (function (Math, undefined) { + var crypto; + + // Native crypto from window (Browser) + if (typeof window !== 'undefined' && window.crypto) { + crypto = window.crypto; + } + + // Native (experimental IE 11) crypto from window (Browser) + if (!crypto && typeof window !== 'undefined' && window.msCrypto) { + crypto = window.msCrypto; + } + + // Native crypto from global (NodeJS) + if (!crypto && typeof global !== 'undefined' && global.crypto) { + crypto = global.crypto; + } + + // Native crypto import via require (NodeJS) + if (!crypto && typeof require === 'function') { + try { + crypto = require('crypto'); + } catch (err) {} + } + /* * Cryptographically secure pseudorandom number generator * * As Math.random() is cryptographically not safe to use */ - var secureRandom = function () { - // Native crypto module on NodeJS environment - try { - // Crypto from global object - var crypto = global.crypto; - - // Create a random float number between 0 and 1 - return Number('0.' + crypto.randomBytes(3).readUIntBE(0, 3)); - } catch (err) {} - - // Native crypto module in Browser environment - try { - // Support experimental crypto module in IE 11 - var crypto = window.crypto || window.msCrypto; + var cryptoSecureRandomInt = function () { + if (crypto) { + // Use getRandomValues method (Browser) + if (typeof crypto.getRandomValues === 'function') { + try { + return crypto.getRandomValues(new Uint32Array(1))[0]; + } catch (err) {} + } - // Create a random float number between 0 and 1 - return Number('0.' + window.crypto.getRandomValues(new Uint32Array(1))[0]); - } catch (err) {} + // Use randomBytes method (NodeJS) + if (typeof crypto.randomBytes === 'function') { + try { + return crypto.randomBytes(4).readInt32LE(); + } catch (err) {} + } + } throw new Error('Native crypto module could not be used to get secure random number.'); }; @@ -334,7 +358,7 @@ var words = []; for (var i = 0; i < nBytes; i += 4) { - words.push((secureRandom() * 0x100000000) | 0); + words.push(cryptoSecureRandomInt()); } return new WordArray.init(words, nBytes); diff --git a/crypto-js.js b/crypto-js.js index 275e7ff..be5c2ea 100644 --- a/crypto-js.js +++ b/crypto-js.js @@ -13,34 +13,58 @@ } }(this, function () { + /*globals window, global, require*/ + /** * CryptoJS core components. */ var CryptoJS = CryptoJS || (function (Math, undefined) { + var crypto; + + // Native crypto from window (Browser) + if (typeof window !== 'undefined' && window.crypto) { + crypto = window.crypto; + } + + // Native (experimental IE 11) crypto from window (Browser) + if (!crypto && typeof window !== 'undefined' && window.msCrypto) { + crypto = window.msCrypto; + } + + // Native crypto from global (NodeJS) + if (!crypto && typeof global !== 'undefined' && global.crypto) { + crypto = global.crypto; + } + + // Native crypto import via require (NodeJS) + if (!crypto && typeof require === 'function') { + try { + crypto = require('crypto'); + } catch (err) {} + } + /* * Cryptographically secure pseudorandom number generator * * As Math.random() is cryptographically not safe to use */ - var secureRandom = function () { - // Native crypto module on NodeJS environment - try { - // Crypto from global object - var crypto = global.crypto; - - // Create a random float number between 0 and 1 - return Number('0.' + crypto.randomBytes(3).readUIntBE(0, 3)); - } catch (err) {} - - // Native crypto module in Browser environment - try { - // Support experimental crypto module in IE 11 - var crypto = window.crypto || window.msCrypto; + var cryptoSecureRandomInt = function () { + if (crypto) { + // Use getRandomValues method (Browser) + if (typeof crypto.getRandomValues === 'function') { + try { + return crypto.getRandomValues(new Uint32Array(1))[0]; + } catch (err) {} + } - // Create a random float number between 0 and 1 - return Number('0.' + window.crypto.getRandomValues(new Uint32Array(1))[0]); - } catch (err) {} + // Use randomBytes method (NodeJS) + if (typeof crypto.randomBytes === 'function') { + try { + return crypto.randomBytes(4).readInt32LE(); + } catch (err) {} + } + } throw new Error('Native crypto module could not be used to get secure random number.'); }; @@ -334,7 +358,7 @@ var words = []; for (var i = 0; i < nBytes; i += 4) { - words.push((secureRandom() * 0x100000000) | 0); + words.push(cryptoSecureRandomInt()); } return new WordArray.init(words, nBytes); diff --git a/package.json b/package.json index ee15327..07f982b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "crypto-js", - "version": "3.2.0", + "version": "3.2.1", "description": "JavaScript library of crypto standards.", "license": "MIT", "author": {