UNPKG

@cbcheng/secure-ls

Version:

Secure sessionStorage or localStorage data with high level of encryption and data compression

1,609 lines (1,390 loc) 174 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("SecureLS", [], factory); else if(typeof exports === 'object') exports["SecureLS"] = factory(); else root["SecureLS"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _utils = __webpack_require__(1); var _utils2 = _interopRequireDefault(_utils); var _constants = __webpack_require__(2); var _constants2 = _interopRequireDefault(_constants); var _encUtf = __webpack_require__(8); var _encUtf2 = _interopRequireDefault(_encUtf); var _Base = __webpack_require__(9); var _Base2 = _interopRequireDefault(_Base); var _lzString = __webpack_require__(10); var _lzString2 = _interopRequireDefault(_lzString); var _aes = __webpack_require__(11); var _aes2 = _interopRequireDefault(_aes); var _tripledes = __webpack_require__(16); var _tripledes2 = _interopRequireDefault(_tripledes); var _rabbit = __webpack_require__(17); var _rabbit2 = _interopRequireDefault(_rabbit); var _rc = __webpack_require__(18); var _rc2 = _interopRequireDefault(_rc); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var SecureLS = function () { function SecureLS(config) { _classCallCheck(this, SecureLS); config = config || {}; this._name = 'secure-ls'; this.utils = _utils2.default; this.constants = _constants2.default; this.Base64 = _Base2.default; this.LZString = _lzString2.default; this.AES = _aes2.default; this.DES = _tripledes2.default; this.RABBIT = _rabbit2.default; this.RC4 = _rc2.default; this.enc = _encUtf2.default; this.config = { isCompression: true, encodingType: _constants2.default.EncrytionTypes.BASE64, encryptionSecret: config.encryptionSecret, encryptionNamespace: config.encryptionNamespace }; this.config.isCompression = typeof config.isCompression !== 'undefined' ? config.isCompression : true; this.config.encodingType = typeof config.encodingType !== 'undefined' || config.encodingType === '' ? config.encodingType.toLowerCase() : _constants2.default.EncrytionTypes.BASE64; this.ls = localStorage; this.init(); } _createClass(SecureLS, [{ key: 'init', value: function init() { var metaData = this.getMetaData(); this.WarningEnum = this.constants.WarningEnum; this.WarningTypes = this.constants.WarningTypes; this.EncrytionTypes = this.constants.EncrytionTypes; this._isBase64 = this._isBase64EncryptionType(); this._isAES = this._isAESEncryptionType(); this._isDES = this._isDESEncryptionType(); this._isRabbit = this._isRabbitEncryptionType(); this._isRC4 = this._isRC4EncryptionType(); this._isCompression = this._isDataCompressionEnabled(); // fill the already present keys to the list of keys being used by secure-ls this.utils.allKeys = metaData.keys || this.resetAllKeys(); } }, { key: '_isBase64EncryptionType', value: function _isBase64EncryptionType() { return _Base2.default && (typeof this.config.encodingType === 'undefined' || this.config.encodingType === this.constants.EncrytionTypes.BASE64); } }, { key: '_isAESEncryptionType', value: function _isAESEncryptionType() { return _aes2.default && this.config.encodingType === this.constants.EncrytionTypes.AES; } }, { key: '_isDESEncryptionType', value: function _isDESEncryptionType() { return _tripledes2.default && this.config.encodingType === this.constants.EncrytionTypes.DES; } }, { key: '_isRabbitEncryptionType', value: function _isRabbitEncryptionType() { return _rabbit2.default && this.config.encodingType === this.constants.EncrytionTypes.RABBIT; } }, { key: '_isRC4EncryptionType', value: function _isRC4EncryptionType() { return _rc2.default && this.config.encodingType === this.constants.EncrytionTypes.RC4; } }, { key: '_isDataCompressionEnabled', value: function _isDataCompressionEnabled() { return this.config.isCompression; } }, { key: 'getEncryptionSecret', value: function getEncryptionSecret(key) { var metaData = this.getMetaData(); var obj = this.utils.getObjectFromKey(metaData.keys, key); if (!obj) { return; } if (this._isAES || this._isDES || this._isRabbit || this._isRC4) { if (typeof this.config.encryptionSecret === 'undefined') { this.utils.encryptionSecret = obj.s; if (!this.utils.encryptionSecret) { this.utils.encryptionSecret = this.utils.generateSecretKey(); this.setMetaData(); } } else { this.utils.encryptionSecret = this.config.encryptionSecret || obj.s || ''; } } } }, { key: 'get', value: function get(key, isAllKeysData) { var decodedData = '', jsonData = '', deCompressedData = void 0, bytes = void 0, data = void 0; if (!this.utils.is(key)) { this.utils.warn(this.WarningEnum.KEY_NOT_PROVIDED); return jsonData; } data = this.getDataFromLocalStorage(key); if (!data) { return jsonData; } deCompressedData = data; // saves else if (this._isCompression || isAllKeysData) { // meta data always compressed deCompressedData = _lzString2.default.decompressFromUTF16(data); } decodedData = deCompressedData; // saves else if (this._isBase64 || isAllKeysData) { // meta data always Base64 decodedData = _Base2.default.decode(deCompressedData); } else { this.getEncryptionSecret(key); if (this._isAES) { bytes = _aes2.default.decrypt(deCompressedData.toString(), this.utils.encryptionSecret); } else if (this._isDES) { bytes = _tripledes2.default.decrypt(deCompressedData.toString(), this.utils.encryptionSecret); } else if (this._isRabbit) { bytes = _rabbit2.default.decrypt(deCompressedData.toString(), this.utils.encryptionSecret); } else if (this._isRC4) { bytes = _rc2.default.decrypt(deCompressedData.toString(), this.utils.encryptionSecret); } if (bytes) { decodedData = bytes.toString(_encUtf2.default._Utf8); } } try { jsonData = JSON.parse(decodedData); } catch (e) { throw new Error('Could not parse JSON'); } return jsonData; } }, { key: 'getDataFromLocalStorage', value: function getDataFromLocalStorage(key) { return this.ls.getItem(key, true); } }, { key: 'getAllKeys', value: function getAllKeys() { var data = this.getMetaData(); return this.utils.extractKeyNames(data) || []; } }, { key: 'set', value: function set(key, data) { var dataToStore = ''; if (!this.utils.is(key)) { this.utils.warn(this.WarningEnum.KEY_NOT_PROVIDED); return; } this.getEncryptionSecret(key); // add key(s) to Array if not already added, only for keys other than meta key if (!(String(key) === String(this.utils.metaKey))) { if (!this.utils.isKeyPresent(key)) { this.utils.addToKeysList(key); this.setMetaData(); } } dataToStore = this.processData(data); // Store the data to localStorage this.setDataToLocalStorage(key, dataToStore); } }, { key: 'setDataToLocalStorage', value: function setDataToLocalStorage(key, data) { this.ls.setItem(key, data); } }, { key: 'remove', value: function remove(key) { if (!this.utils.is(key)) { this.utils.warn(this.WarningEnum.KEY_NOT_PROVIDED); return; } if (key === this.utils.metaKey && this.getAllKeys().length) { this.utils.warn(this.WarningEnum.META_KEY_REMOVE); return; } if (this.utils.isKeyPresent(key)) { this.utils.removeFromKeysList(key); this.setMetaData(); } this.ls.removeItem(key); } }, { key: 'removeAll', value: function removeAll() { var keys = void 0, i = void 0; keys = this.getAllKeys(); for (i = 0; i < keys.length; i++) { this.ls.removeItem(keys[i]); } this.ls.removeItem(this.utils.metaKey); this.resetAllKeys(); } }, { key: 'clear', value: function clear() { this.ls.clear(); this.resetAllKeys(); } }, { key: 'resetAllKeys', value: function resetAllKeys() { this.utils.allKeys = []; return []; } }, { key: 'processData', value: function processData(data, isAllKeysData) { if (data === null || data === undefined || data === '') { return ''; } var jsonData = void 0, encodedData = void 0, compressedData = void 0; try { jsonData = JSON.stringify(data); } catch (e) { throw new Error('Could not stringify data.'); } // Encode Based on encoding type // If not set, default to Base64 for securing data encodedData = jsonData; if (this._isBase64 || isAllKeysData) { encodedData = _Base2.default.encode(jsonData); } else { if (this._isAES) { encodedData = _aes2.default.encrypt(jsonData, this.utils.encryptionSecret); } else if (this._isDES) { encodedData = _tripledes2.default.encrypt(jsonData, this.utils.encryptionSecret); } else if (this._isRabbit) { encodedData = _rabbit2.default.encrypt(jsonData, this.utils.encryptionSecret); } else if (this._isRC4) { encodedData = _rc2.default.encrypt(jsonData, this.utils.encryptionSecret); } encodedData = encodedData && encodedData.toString(); } // Compress data if set to true compressedData = encodedData; if (this._isCompression || isAllKeysData) { compressedData = _lzString2.default.compressToUTF16(encodedData); } return compressedData; } }, { key: 'setMetaData', value: function setMetaData() { var dataToStore = this.processData({ keys: this.utils.allKeys }, true); // Store the data to localStorage this.setDataToLocalStorage(this.getMetaKey(), dataToStore); } }, { key: 'getMetaData', value: function getMetaData() { return this.get(this.getMetaKey(), true) || {}; } }, { key: 'getMetaKey', value: function getMetaKey() { return this.utils.metaKey + (this.config.encryptionNamespace ? '__' + this.config.encryptionNamespace : ''); } }]); return SecureLS; }(); exports.default = SecureLS; ; module.exports = exports['default']; /***/ }, /* 1 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _constants = __webpack_require__(2); var _constants2 = _interopRequireDefault(_constants); var _WordArray = __webpack_require__(3); var _WordArray2 = _interopRequireDefault(_WordArray); var _pbkdf = __webpack_require__(4); var _pbkdf2 = _interopRequireDefault(_pbkdf); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var utils = { metaKey: '_secure__ls__metadata', encryptionSecret: '', secretPhrase: 's3cr3t$#@135^&*246', allKeys: [], is: function is(key) { if (key) { return true; } return false; }, warn: function warn(reason) { reason = reason ? reason : _constants2.default.WarningEnum.DEFAULT_TEXT; console.warn(_constants2.default.WarningTypes[reason]); }, generateSecretKey: function generateSecretKey() { var salt = _WordArray2.default.random(128 / 8); var key128Bits = (0, _pbkdf2.default)(this.secretPhrase, salt, { keySize: 128 / 32 }); return key128Bits && key128Bits.toString(); }, getObjectFromKey: function getObjectFromKey(data, key) { if (!data || !data.length) { return {}; } var i = void 0, obj = {}; for (i = 0; i < data.length; i++) { if (data[i].k === key) { obj = data[i]; break; } } return obj; }, extractKeyNames: function extractKeyNames(data) { if (!data || !data.keys || !data.keys.length) { return []; } return data.keys.map(function (keyData) { return keyData.k; }); }, getAllKeys: function getAllKeys() { return this.allKeys; }, isKeyPresent: function isKeyPresent(key) { var isKeyAlreadyPresent = false; for (var i = 0; i < this.allKeys.length; i++) { if (String(this.allKeys[i].k) === String(key)) { isKeyAlreadyPresent = true; // found break; } } return isKeyAlreadyPresent; }, addToKeysList: function addToKeysList(key) { this.allKeys.push({ k: key, s: this.encryptionSecret }); }, removeFromKeysList: function removeFromKeysList(key) { var i = void 0, index = -1; for (i = 0; i < this.allKeys.length; i++) { if (this.allKeys[i].k === key) { index = i; break; } } if (index !== -1) { this.allKeys.splice(index, 1); } return index; } }; module.exports = utils; /***/ }, /* 2 */ /***/ function(module, exports) { 'use strict'; var WarningEnum = { KEY_NOT_PROVIDED: 'keyNotProvided', META_KEY_REMOVE: 'metaKeyRemove', DEFAULT_TEXT: 'defaultText' }; var WarningTypes = {}; WarningTypes[WarningEnum.KEY_NOT_PROVIDED] = 'Secure LS: Key not provided. Aborting operation!'; WarningTypes[WarningEnum.META_KEY_REMOVE] = 'Secure LS: Meta key can not be removed\nunless all keys created by Secure LS are removed!'; WarningTypes[WarningEnum.DEFAULT_TEXT] = 'Unexpected output'; var constants = { WarningEnum: WarningEnum, WarningTypes: WarningTypes, EncrytionTypes: { BASE64: 'base64', AES: 'aes', DES: 'des', RABBIT: 'rabbit', RC4: 'rc4' } }; module.exports = constants; /***/ }, /* 3 */ /***/ function(module, exports) { "use strict"; /* ES6 compatible port of CryptoJS - WordArray for PBKDF2 password key generation Source: https://github.com/brix/crypto-js LICENSE: MIT */ var CryptoJSWordArray = {}; CryptoJSWordArray.random = function (nBytes) { var words = []; var r = function r(mw) { var mz = 0x3ade68b1; var mask = 0xffffffff; return function () { mz = 0x9069 * (mz & 0xFFFF) + (mz >> 0x10) & mask; mw = 0x4650 * (mw & 0xFFFF) + (mw >> 0x10) & mask; var result = (mz << 0x10) + mw & mask; result /= 0x100000000; result += 0.5; return result * (Math.random() > 0.5 ? 1 : -1); }; }; for (var i = 0, rcache; i < nBytes; i += 4) { var _r = r((rcache || Math.random()) * 0x100000000); rcache = _r() * 0x3ade67b7; words.push(_r() * 0x100000000 | 0); } return new this.Set(words, nBytes); }; CryptoJSWordArray.Set = function (words, sigBytes) { words = this.words = words || []; if (sigBytes !== undefined) { this.sigBytes = sigBytes; } else { this.sigBytes = words.length * 8; } }; module.exports = CryptoJSWordArray; /***/ }, /* 4 */ /***/ function(module, exports, __webpack_require__) { ;(function (root, factory, undef) { if (true) { // CommonJS module.exports = exports = factory(__webpack_require__(5), __webpack_require__(6), __webpack_require__(7)); } else if (typeof define === "function" && define.amd) { // AMD define(["./core", "./sha1", "./hmac"], factory); } else { // Global (browser) factory(root.CryptoJS); } }(this, function (CryptoJS) { (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var WordArray = C_lib.WordArray; var C_algo = C.algo; var SHA1 = C_algo.SHA1; var HMAC = C_algo.HMAC; /** * Password-Based Key Derivation Function 2 algorithm. */ var PBKDF2 = C_algo.PBKDF2 = Base.extend({ /** * Configuration options. * * @property {number} keySize The key size in words to generate. Default: 4 (128 bits) * @property {Hasher} hasher The hasher to use. Default: SHA1 * @property {number} iterations The number of iterations to perform. Default: 1 */ cfg: Base.extend({ keySize: 128/32, hasher: SHA1, iterations: 1 }), /** * Initializes a newly created key derivation function. * * @param {Object} cfg (Optional) The configuration options to use for the derivation. * * @example * * var kdf = CryptoJS.algo.PBKDF2.create(); * var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8 }); * var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8, iterations: 1000 }); */ init: function (cfg) { this.cfg = this.cfg.extend(cfg); }, /** * Computes the Password-Based Key Derivation Function 2. * * @param {WordArray|string} password The password. * @param {WordArray|string} salt A salt. * * @return {WordArray} The derived key. * * @example * * var key = kdf.compute(password, salt); */ compute: function (password, salt) { // Shortcut var cfg = this.cfg; // Init HMAC var hmac = HMAC.create(cfg.hasher, password); // Initial values var derivedKey = WordArray.create(); var blockIndex = WordArray.create([0x00000001]); // Shortcuts var derivedKeyWords = derivedKey.words; var blockIndexWords = blockIndex.words; var keySize = cfg.keySize; var iterations = cfg.iterations; // Generate key while (derivedKeyWords.length < keySize) { var block = hmac.update(salt).finalize(blockIndex); hmac.reset(); // Shortcuts var blockWords = block.words; var blockWordsLength = blockWords.length; // Iterations var intermediate = block; for (var i = 1; i < iterations; i++) { intermediate = hmac.finalize(intermediate); hmac.reset(); // Shortcut var intermediateWords = intermediate.words; // XOR intermediate with block for (var j = 0; j < blockWordsLength; j++) { blockWords[j] ^= intermediateWords[j]; } } derivedKey.concat(block); blockIndexWords[0]++; } derivedKey.sigBytes = keySize * 4; return derivedKey; } }); /** * Computes the Password-Based Key Derivation Function 2. * * @param {WordArray|string} password The password. * @param {WordArray|string} salt A salt. * @param {Object} cfg (Optional) The configuration options to use for this computation. * * @return {WordArray} The derived key. * * @static * * @example * * var key = CryptoJS.PBKDF2(password, salt); * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 }); * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 }); */ C.PBKDF2 = function (password, salt, cfg) { return PBKDF2.create(cfg).compute(password, salt); }; }()); return CryptoJS.PBKDF2; })); /***/ }, /* 5 */ /***/ function(module, exports, __webpack_require__) { ;(function (root, factory) { if (true) { // CommonJS module.exports = exports = factory(); } else if (typeof define === "function" && define.amd) { // AMD define([], factory); } else { // Global (browser) root.CryptoJS = factory(); } }(this, function () { /** * CryptoJS core components. */ var CryptoJS = CryptoJS || (function (Math, undefined) { /* * Local polyfil of Object.create */ var create = Object.create || (function () { function F() {}; return function (obj) { var subtype; F.prototype = obj; subtype = new F(); F.prototype = null; return subtype; }; }()) /** * CryptoJS namespace. */ var C = {}; /** * Library namespace. */ var C_lib = C.lib = {}; /** * Base object for prototypal inheritance. */ var Base = C_lib.Base = (function () { return { /** * Creates a new object that inherits from this object. * * @param {Object} overrides Properties to copy into the new object. * * @return {Object} The new object. * * @static * * @example * * var MyType = CryptoJS.lib.Base.extend({ * field: 'value', * * method: function () { * } * }); */ extend: function (overrides) { // Spawn var subtype = create(this); // Augment if (overrides) { subtype.mixIn(overrides); } // Create default initializer if (!subtype.hasOwnProperty('init') || this.init === subtype.init) { subtype.init = function () { subtype.$super.init.apply(this, arguments); }; } // Initializer's prototype is the subtype object subtype.init.prototype = subtype; // Reference supertype subtype.$super = this; return subtype; }, /** * Extends this object and runs the init method. * Arguments to create() will be passed to init(). * * @return {Object} The new object. * * @static * * @example * * var instance = MyType.create(); */ create: function () { var instance = this.extend(); instance.init.apply(instance, arguments); return instance; }, /** * Initializes a newly created object. * Override this method to add some logic when your objects are created. * * @example * * var MyType = CryptoJS.lib.Base.extend({ * init: function () { * // ... * } * }); */ init: function () { }, /** * Copies properties into this object. * * @param {Object} properties The properties to mix in. * * @example * * MyType.mixIn({ * field: 'value' * }); */ mixIn: function (properties) { for (var propertyName in properties) { if (properties.hasOwnProperty(propertyName)) { this[propertyName] = properties[propertyName]; } } // IE won't copy toString using the loop above if (properties.hasOwnProperty('toString')) { this.toString = properties.toString; } }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = instance.clone(); */ clone: function () { return this.init.prototype.extend(this); } }; }()); /** * An array of 32-bit words. * * @property {Array} words The array of 32-bit words. * @property {number} sigBytes The number of significant bytes in this word array. */ var WordArray = C_lib.WordArray = Base.extend({ /** * Initializes a newly created word array. * * @param {Array} words (Optional) An array of 32-bit words. * @param {number} sigBytes (Optional) The number of significant bytes in the words. * * @example * * var wordArray = CryptoJS.lib.WordArray.create(); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); */ init: function (words, sigBytes) { words = this.words = words || []; if (sigBytes != undefined) { this.sigBytes = sigBytes; } else { this.sigBytes = words.length * 4; } }, /** * Converts this word array to a string. * * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex * * @return {string} The stringified word array. * * @example * * var string = wordArray + ''; * var string = wordArray.toString(); * var string = wordArray.toString(CryptoJS.enc.Utf8); */ toString: function (encoder) { return (encoder || Hex).stringify(this); }, /** * Concatenates a word array to this word array. * * @param {WordArray} wordArray The word array to append. * * @return {WordArray} This word array. * * @example * * wordArray1.concat(wordArray2); */ concat: function (wordArray) { // Shortcuts var thisWords = this.words; var thatWords = wordArray.words; var thisSigBytes = this.sigBytes; var thatSigBytes = wordArray.sigBytes; // Clamp excess bits this.clamp(); // Concat if (thisSigBytes % 4) { // Copy one byte at a time for (var i = 0; i < thatSigBytes; i++) { var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); } } else { // Copy one word at a time for (var i = 0; i < thatSigBytes; i += 4) { thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; } } this.sigBytes += thatSigBytes; // Chainable return this; }, /** * Removes insignificant bits. * * @example * * wordArray.clamp(); */ clamp: function () { // Shortcuts var words = this.words; var sigBytes = this.sigBytes; // Clamp words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); words.length = Math.ceil(sigBytes / 4); }, /** * Creates a copy of this word array. * * @return {WordArray} The clone. * * @example * * var clone = wordArray.clone(); */ clone: function () { var clone = Base.clone.call(this); clone.words = this.words.slice(0); return clone; }, /** * Creates a word array filled with random bytes. * * @param {number} nBytes The number of random bytes to generate. * * @return {WordArray} The random word array. * * @static * * @example * * var wordArray = CryptoJS.lib.WordArray.random(16); */ random: function (nBytes) { var words = []; var r = (function (m_w) { var m_w = m_w; var m_z = 0x3ade68b1; var mask = 0xffffffff; return function () { m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask; m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask; var result = ((m_z << 0x10) + m_w) & mask; result /= 0x100000000; result += 0.5; return result * (Math.random() > .5 ? 1 : -1); } }); for (var i = 0, rcache; i < nBytes; i += 4) { var _r = r((rcache || Math.random()) * 0x100000000); rcache = _r() * 0x3ade67b7; words.push((_r() * 0x100000000) | 0); } return new WordArray.init(words, nBytes); } }); /** * Encoder namespace. */ var C_enc = C.enc = {}; /** * Hex encoding strategy. */ var Hex = C_enc.Hex = { /** * Converts a word array to a hex string. * * @param {WordArray} wordArray The word array. * * @return {string} The hex string. * * @static * * @example * * var hexString = CryptoJS.enc.Hex.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var hexChars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; hexChars.push((bite >>> 4).toString(16)); hexChars.push((bite & 0x0f).toString(16)); } return hexChars.join(''); }, /** * Converts a hex string to a word array. * * @param {string} hexStr The hex string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Hex.parse(hexString); */ parse: function (hexStr) { // Shortcut var hexStrLength = hexStr.length; // Convert var words = []; for (var i = 0; i < hexStrLength; i += 2) { words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); } return new WordArray.init(words, hexStrLength / 2); } }; /** * Latin1 encoding strategy. */ var Latin1 = C_enc.Latin1 = { /** * Converts a word array to a Latin1 string. * * @param {WordArray} wordArray The word array. * * @return {string} The Latin1 string. * * @static * * @example * * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var latin1Chars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; latin1Chars.push(String.fromCharCode(bite)); } return latin1Chars.join(''); }, /** * Converts a Latin1 string to a word array. * * @param {string} latin1Str The Latin1 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); */ parse: function (latin1Str) { // Shortcut var latin1StrLength = latin1Str.length; // Convert var words = []; for (var i = 0; i < latin1StrLength; i++) { words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); } return new WordArray.init(words, latin1StrLength); } }; /** * UTF-8 encoding strategy. */ var Utf8 = C_enc.Utf8 = { /** * Converts a word array to a UTF-8 string. * * @param {WordArray} wordArray The word array. * * @return {string} The UTF-8 string. * * @static * * @example * * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); */ stringify: function (wordArray) { try { return decodeURIComponent(escape(Latin1.stringify(wordArray))); } catch (e) { throw new Error('Malformed UTF-8 data'); } }, /** * Converts a UTF-8 string to a word array. * * @param {string} utf8Str The UTF-8 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); */ parse: function (utf8Str) { return Latin1.parse(unescape(encodeURIComponent(utf8Str))); } }; /** * Abstract buffered block algorithm template. * * The property blockSize must be implemented in a concrete subtype. * * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 */ var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ /** * Resets this block algorithm's data buffer to its initial state. * * @example * * bufferedBlockAlgorithm.reset(); */ reset: function () { // Initial values this._data = new WordArray.init(); this._nDataBytes = 0; }, /** * Adds new data to this block algorithm's buffer. * * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. * * @example * * bufferedBlockAlgorithm._append('data'); * bufferedBlockAlgorithm._append(wordArray); */ _append: function (data) { // Convert string to WordArray, else assume WordArray already if (typeof data == 'string') { data = Utf8.parse(data); } // Append this._data.concat(data); this._nDataBytes += data.sigBytes; }, /** * Processes available data blocks. * * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. * * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. * * @return {WordArray} The processed data. * * @example * * var processedData = bufferedBlockAlgorithm._process(); * var processedData = bufferedBlockAlgorithm._process(!!'flush'); */ _process: function (doFlush) { // Shortcuts var data = this._data; var dataWords = data.words; var dataSigBytes = data.sigBytes; var blockSize = this.blockSize; var blockSizeBytes = blockSize * 4; // Count blocks ready var nBlocksReady = dataSigBytes / blockSizeBytes; if (doFlush) { // Round up to include partial blocks nBlocksReady = Math.ceil(nBlocksReady); } else { // Round down to include only full blocks, // less the number of blocks that must remain in the buffer nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); } // Count words ready var nWordsReady = nBlocksReady * blockSize; // Count bytes ready var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); // Process blocks if (nWordsReady) { for (var offset = 0; offset < nWordsReady; offset += blockSize) { // Perform concrete-algorithm logic this._doProcessBlock(dataWords, offset); } // Remove processed words var processedWords = dataWords.splice(0, nWordsReady); data.sigBytes -= nBytesReady; } // Return processed words return new WordArray.init(processedWords, nBytesReady); }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = bufferedBlockAlgorithm.clone(); */ clone: function () { var clone = Base.clone.call(this); clone._data = this._data.clone(); return clone; }, _minBufferSize: 0 }); /** * Abstract hasher template. * * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) */ var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ /** * Configuration options. */ cfg: Base.extend(), /** * Initializes a newly created hasher. * * @param {Object} cfg (Optional) The configuration options to use for this hash computation. * * @example * * var hasher = CryptoJS.algo.SHA256.create(); */ init: function (cfg) { // Apply config defaults this.cfg = this.cfg.extend(cfg); // Set initial values this.reset(); }, /** * Resets this hasher to its initial state. * * @example * * hasher.reset(); */ reset: function () { // Reset data buffer BufferedBlockAlgorithm.reset.call(this); // Perform concrete-hasher logic this._doReset(); }, /** * Updates this hasher with a message. * * @param {WordArray|string} messageUpdate The message to append. * * @return {Hasher} This hasher. * * @example * * hasher.update('message'); * hasher.update(wordArray); */ update: function (messageUpdate) { // Append this._append(messageUpdate); // Update the hash this._process(); // Chainable return this; }, /** * Finalizes the hash computation. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} messageUpdate (Optional) A final message update. * * @return {WordArray} The hash. * * @example * * var hash = hasher.finalize(); * var hash = hasher.finalize('message'); * var hash = hasher.finalize(wordArray); */ finalize: function (messageUpdate) { // Final message update if (messageUpdate) { this._append(messageUpdate); } // Perform concrete-hasher logic var hash = this._doFinalize(); return hash; }, blockSize: 512/32, /** * Creates a shortcut function to a hasher's object interface. * * @param {Hasher} hasher The hasher to create a helper for. * * @return {Function} The shortcut function. * * @static * * @example * * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); */ _createHelper: function (hasher) { return function (message, cfg) { return new hasher.init(cfg).finalize(message); }; }, /** * Creates a shortcut function to the HMAC's object interface. * * @param {Hasher} hasher The hasher to use in this HMAC helper. * * @return {Function} The shortcut function. * * @static * * @example * * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); */ _createHmacHelper: function (hasher) { return function (message, key) { return new C_algo.HMAC.init(hasher, key).finalize(message); }; } }); /** * Algorithm namespace. */ var C_algo = C.algo = {}; return C; }(Math)); return CryptoJS; })); /***/ }, /* 6 */ /***/ function(module, exports, __webpack_require__) { ;(function (root, factory) { if (true) { // CommonJS module.exports = exports = factory(__webpack_require__(5)); } else if (typeof define === "function" && define.amd) { // AMD define(["./core"], factory); } else { // Global (browser) factory(root.CryptoJS); } }(this, function (CryptoJS) { (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; // Reusable object var W = []; /** * SHA-1 hash algorithm. */ var SHA1 = C_algo.SHA1 = Hasher.extend({ _doReset: function () { this._hash = new WordArray.init([ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]); }, _doProcessBlock: function (M, offset) { // Shortcut var H = this._hash.words; // Working variables var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; var e = H[4]; // Computation for (var i = 0; i < 80; i++) { if (i < 16) { W[i] = M[offset + i] | 0; } else { var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; W[i] = (n << 1) | (n >>> 31); } var t = ((a << 5) | (a >>> 27)) + e + W[i]; if (i < 20) { t += ((b & c) | (~b & d)) + 0x5a827999; } else if (i < 40) { t += (b ^ c ^ d) + 0x6ed9eba1; } else if (i < 60) { t += ((b & c) | (b & d) | (c & d)) - 0x70e44324; } else /* if (i < 80) */ { t += (b ^ c ^ d) - 0x359d3e2a; } e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t; } // Intermediate hash value H[0] =