3
code.google.com/p/crypto-js
4
(c) 2009-2012 by Jeff Mott. All rights reserved.
5
code.google.com/p/crypto-js/wiki/License
8
* CryptoJS core components.
10
var CryptoJS = CryptoJS || (function (Math, undefined) {
19
var C_lib = C.lib = {};
22
* Base object for prototypal inheritance.
24
var Base = C_lib.Base = (function () {
29
* Creates a new object that inherits from this object.
31
* @param {Object} overrides Properties to copy into the new object.
33
* @return {Object} The new object.
39
* var MyType = CryptoJS.lib.Base.extend({
42
* method: function () {
46
extend: function (overrides) {
49
var subtype = new F();
53
subtype.mixIn(overrides);
56
// Reference supertype
57
subtype.$super = this;
63
* Extends this object and runs the init method.
64
* Arguments to create() will be passed to init().
66
* @return {Object} The new object.
72
* var instance = MyType.create();
75
var instance = this.extend();
76
instance.init.apply(instance, arguments);
82
* Initializes a newly created object.
83
* Override this method to add some logic when your objects are created.
87
* var MyType = CryptoJS.lib.Base.extend({
97
* Copies properties into this object.
99
* @param {Object} properties The properties to mix in.
107
mixIn: function (properties) {
108
for (var propertyName in properties) {
109
if (properties.hasOwnProperty(propertyName)) {
110
this[propertyName] = properties[propertyName];
114
// IE won't copy toString using the loop above
115
// Other non-enumerable properties are:
116
// hasOwnProperty, isPrototypeOf, propertyIsEnumerable,
117
// toLocaleString, valueOf
118
if (properties.hasOwnProperty('toString')) {
119
this.toString = properties.toString;
124
* Creates a copy of this object.
126
* @return {Object} The clone.
130
* var clone = instance.clone();
133
return this.$super.extend(this);
139
* An array of 32-bit words.
141
* @property {Array} words The array of 32-bit words.
142
* @property {number} sigBytes The number of significant bytes in this word array.
144
var WordArray = C_lib.WordArray = Base.extend({
146
* Initializes a newly created word array.
148
* @param {Array} words (Optional) An array of 32-bit words.
149
* @param {number} sigBytes (Optional) The number of significant bytes in the words.
153
* var wordArray = CryptoJS.lib.WordArray.create();
154
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
155
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
157
init: function (words, sigBytes) {
158
words = this.words = words || [];
160
if (sigBytes != undefined) {
161
this.sigBytes = sigBytes;
163
this.sigBytes = words.length * 4;
168
* Converts this word array to a string.
170
* @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
172
* @return {string} The stringified word array.
176
* var string = wordArray + '';
177
* var string = wordArray.toString();
178
* var string = wordArray.toString(CryptoJS.enc.Utf8);
180
toString: function (encoder) {
181
return (encoder || Hex).stringify(this);
185
* Concatenates a word array to this word array.
187
* @param {WordArray} wordArray The word array to append.
189
* @return {WordArray} This word array.
193
* wordArray1.concat(wordArray2);
195
concat: function (wordArray) {
197
var thisWords = this.words;
198
var thatWords = wordArray.words;
199
var thisSigBytes = this.sigBytes;
200
var thatSigBytes = wordArray.sigBytes;
206
if (thisSigBytes % 4) {
207
// Copy one byte at a time
208
for (var i = 0; i < thatSigBytes; i++) {
209
var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
210
thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
212
} else if (thatWords.length > 0xffff) {
213
// Copy one word at a time
214
for (var i = 0; i < thatSigBytes; i += 4) {
215
thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
218
// Copy all words at once
219
thisWords.push.apply(thisWords, thatWords);
221
this.sigBytes += thatSigBytes;
228
* Removes insignificant bits.
236
var words = this.words;
237
var sigBytes = this.sigBytes;
240
words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
241
words.length = Math.ceil(sigBytes / 4);
245
* Creates a copy of this word array.
247
* @return {WordArray} The clone.
251
* var clone = wordArray.clone();
254
var clone = Base.clone.call(this);
255
clone.words = this.words.slice(0);
261
* Creates a word array filled with random bytes.
263
* @param {number} nBytes The number of random bytes to generate.
265
* @return {WordArray} The random word array.
271
* var wordArray = CryptoJS.lib.WordArray.random(16);
273
random: function (nBytes) {
275
for (var i = 0; i < nBytes; i += 4) {
276
words.push((Math.random() * 0x100000000) | 0);
279
return WordArray.create(words, nBytes);
286
var C_enc = C.enc = {};
289
* Hex encoding strategy.
291
var Hex = C_enc.Hex = {
293
* Converts a word array to a hex string.
295
* @param {WordArray} wordArray The word array.
297
* @return {string} The hex string.
303
* var hexString = CryptoJS.enc.Hex.stringify(wordArray);
305
stringify: function (wordArray) {
307
var words = wordArray.words;
308
var sigBytes = wordArray.sigBytes;
312
for (var i = 0; i < sigBytes; i++) {
313
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
314
hexChars.push((bite >>> 4).toString(16));
315
hexChars.push((bite & 0x0f).toString(16));
318
return hexChars.join('');
322
* Converts a hex string to a word array.
324
* @param {string} hexStr The hex string.
326
* @return {WordArray} The word array.
332
* var wordArray = CryptoJS.enc.Hex.parse(hexString);
334
parse: function (hexStr) {
336
var hexStrLength = hexStr.length;
340
for (var i = 0; i < hexStrLength; i += 2) {
341
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
344
return WordArray.create(words, hexStrLength / 2);
349
* Latin1 encoding strategy.
351
var Latin1 = C_enc.Latin1 = {
353
* Converts a word array to a Latin1 string.
355
* @param {WordArray} wordArray The word array.
357
* @return {string} The Latin1 string.
363
* var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
365
stringify: function (wordArray) {
367
var words = wordArray.words;
368
var sigBytes = wordArray.sigBytes;
371
var latin1Chars = [];
372
for (var i = 0; i < sigBytes; i++) {
373
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
374
latin1Chars.push(String.fromCharCode(bite));
377
return latin1Chars.join('');
381
* Converts a Latin1 string to a word array.
383
* @param {string} latin1Str The Latin1 string.
385
* @return {WordArray} The word array.
391
* var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
393
parse: function (latin1Str) {
395
var latin1StrLength = latin1Str.length;
399
for (var i = 0; i < latin1StrLength; i++) {
400
words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
403
return WordArray.create(words, latin1StrLength);
408
* UTF-8 encoding strategy.
410
var Utf8 = C_enc.Utf8 = {
412
* Converts a word array to a UTF-8 string.
414
* @param {WordArray} wordArray The word array.
416
* @return {string} The UTF-8 string.
422
* var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
424
stringify: function (wordArray) {
426
return decodeURIComponent(escape(Latin1.stringify(wordArray)));
428
throw new Error('Malformed UTF-8 data');
433
* Converts a UTF-8 string to a word array.
435
* @param {string} utf8Str The UTF-8 string.
437
* @return {WordArray} The word array.
443
* var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
445
parse: function (utf8Str) {
446
return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
451
* Abstract buffered block algorithm template.
452
* The property blockSize must be implemented in a concrete subtype.
454
* @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
456
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
458
* Resets this block algorithm's data buffer to its initial state.
462
* bufferedBlockAlgorithm.reset();
466
this._data = WordArray.create();
467
this._nDataBytes = 0;
471
* Adds new data to this block algorithm's buffer.
473
* @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
477
* bufferedBlockAlgorithm._append('data');
478
* bufferedBlockAlgorithm._append(wordArray);
480
_append: function (data) {
481
// Convert string to WordArray, else assume WordArray already
482
if (typeof data == 'string') {
483
data = Utf8.parse(data);
487
this._data.concat(data);
488
this._nDataBytes += data.sigBytes;
492
* Processes available data blocks.
493
* This method invokes _doProcessBlock(dataWords, offset), which must be implemented by a concrete subtype.
495
* @param {boolean} flush Whether all blocks and partial blocks should be processed.
497
* @return {WordArray} The data after processing.
501
* var processedData = bufferedBlockAlgorithm._process();
502
* var processedData = bufferedBlockAlgorithm._process(!!'flush');
504
_process: function (flush) {
506
var data = this._data;
507
var dataWords = data.words;
508
var dataSigBytes = data.sigBytes;
509
var blockSize = this.blockSize;
510
var blockSizeBytes = blockSize * 4;
512
// Count blocks ready
513
var nBlocksReady = dataSigBytes / blockSizeBytes;
515
// Round up to include partial blocks
516
nBlocksReady = Math.ceil(nBlocksReady);
518
// Round down to include only full blocks,
519
// less the number of blocks that must remain in the buffer
520
nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
524
var nWordsReady = nBlocksReady * blockSize;
527
var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
531
for (var offset = 0; offset < nWordsReady; offset += blockSize) {
532
// Perform concrete-algorithm logic
533
this._doProcessBlock(dataWords, offset);
536
// Remove processed words
537
var processedWords = dataWords.splice(0, nWordsReady);
538
data.sigBytes -= nBytesReady;
541
// Return processed words
542
return WordArray.create(processedWords, nBytesReady);
546
* Creates a copy of this object.
548
* @return {Object} The clone.
552
* var clone = bufferedBlockAlgorithm.clone();
555
var clone = Base.clone.call(this);
556
clone._data = this._data.clone();
565
* Abstract hasher template.
567
* @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
569
var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
571
* Configuration options.
573
// cfg: Base.extend(),
576
* Initializes a newly created hasher.
578
* @param {Object} cfg (Optional) The configuration options to use for this hash computation.
582
* var hasher = CryptoJS.algo.SHA256.create();
584
init: function (cfg) {
585
// Apply config defaults
586
// this.cfg = this.cfg.extend(cfg);
588
// Set initial values
593
* Resets this hasher to its initial state.
601
BufferedBlockAlgorithm.reset.call(this);
603
// Perform concrete-hasher logic
608
* Updates this hasher with a message.
610
* @param {WordArray|string} messageUpdate The message to append.
612
* @return {Hasher} This hasher.
616
* hasher.update('message');
617
* hasher.update(wordArray);
619
update: function (messageUpdate) {
621
this._append(messageUpdate);
631
* Finalizes the hash computation.
632
* Note that the finalize operation is effectively a destructive, read-once operation.
634
* @param {WordArray|string} messageUpdate (Optional) A final message update.
636
* @return {WordArray} The hash.
640
* var hash = hasher.finalize();
641
* var hash = hasher.finalize('message');
642
* var hash = hasher.finalize(wordArray);
644
finalize: function (messageUpdate) {
645
// Final message update
647
this._append(messageUpdate);
650
// Perform concrete-hasher logic
657
* Creates a copy of this object.
659
* @return {Object} The clone.
663
* var clone = hasher.clone();
666
var clone = BufferedBlockAlgorithm.clone.call(this);
667
clone._hash = this._hash.clone();
675
* Creates a shortcut function to a hasher's object interface.
677
* @param {Hasher} hasher The hasher to create a helper for.
679
* @return {Function} The shortcut function.
685
* var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
687
_createHelper: function (hasher) {
688
return function (message, cfg) {
689
return hasher.create(cfg).finalize(message);
694
* Creates a shortcut function to the HMAC's object interface.
696
* @param {Hasher} hasher The hasher to use in this HMAC helper.
698
* @return {Function} The shortcut function.
704
* var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
706
_createHmacHelper: function (hasher) {
707
return function (message, key) {
708
return C_algo.HMAC.create(hasher, key).finalize(message);
714
* Algorithm namespace.
716
var C_algo = C.algo = {};