@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
JavaScript
(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] =