You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
711 lines
20 KiB
711 lines
20 KiB
/*! CryptoJS v3.1.2 core-fix.js |
|
* code.google.com/p/crypto-js |
|
* (c) 2009-2013 by Jeff Mott. All rights reserved. |
|
* code.google.com/p/crypto-js/wiki/License |
|
* THIS IS FIX of 'core.js' to fix Hmac issue. |
|
* https://code.google.com/p/crypto-js/issues/detail?id=84 |
|
* https://crypto-js.googlecode.com/svn-history/r667/branches/3.x/src/core.js |
|
*/ |
|
/** |
|
* CryptoJS core components. |
|
*/ |
|
var CryptoJS = CryptoJS || (function (Math, undefined) { |
|
/** |
|
* CryptoJS namespace. |
|
*/ |
|
var C = {}; |
|
|
|
/** |
|
* Library namespace. |
|
*/ |
|
var C_lib = C.lib = {}; |
|
|
|
/** |
|
* Base object for prototypal inheritance. |
|
*/ |
|
var Base = C_lib.Base = (function () { |
|
function F() {} |
|
|
|
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 |
|
F.prototype = this; |
|
var subtype = new F(); |
|
|
|
// Augment |
|
if (overrides) { |
|
subtype.mixIn(overrides); |
|
} |
|
|
|
// Create default initializer |
|
if (!subtype.hasOwnProperty('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 = []; |
|
for (var i = 0; i < nBytes; i += 4) { |
|
words.push((Math.random() * 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));
|
|
|