UNPKG

23.3 kBJavaScriptView Raw
1;(function (root, factory) {
2 if (typeof exports === "object") {
3 // CommonJS
4 module.exports = exports = factory();
5 }
6 else if (typeof define === "function" && define.amd) {
7 // AMD
8 define([], factory);
9 }
10 else {
11 // Global (browser)
12 root.CryptoJS = factory();
13 }
14}(this, function () {
15
16 /*globals window, global, require*/
17
18 /**
19 * CryptoJS core components.
20 */
21 var CryptoJS = CryptoJS || (function (Math, undefined) {
22
23 var crypto;
24
25 // Native crypto from window (Browser)
26 if (typeof window !== 'undefined' && window.crypto) {
27 crypto = window.crypto;
28 }
29
30 // Native (experimental IE 11) crypto from window (Browser)
31 if (!crypto && typeof window !== 'undefined' && window.msCrypto) {
32 crypto = window.msCrypto;
33 }
34
35 // Native crypto from global (NodeJS)
36 if (!crypto && typeof global !== 'undefined' && global.crypto) {
37 crypto = global.crypto;
38 }
39
40 // Native crypto import via require (NodeJS)
41 if (!crypto && typeof require === 'function') {
42 try {
43 crypto = require('crypto');
44 } catch (err) {}
45 }
46
47 /*
48 * Cryptographically secure pseudorandom number generator
49 *
50 * As Math.random() is cryptographically not safe to use
51 */
52 var cryptoSecureRandomInt = function () {
53 if (crypto) {
54 // Use getRandomValues method (Browser)
55 if (typeof crypto.getRandomValues === 'function') {
56 try {
57 return crypto.getRandomValues(new Uint32Array(1))[0];
58 } catch (err) {}
59 }
60
61 // Use randomBytes method (NodeJS)
62 if (typeof crypto.randomBytes === 'function') {
63 try {
64 return crypto.randomBytes(4).readInt32LE();
65 } catch (err) {}
66 }
67 }
68
69 throw new Error('Native crypto module could not be used to get secure random number.');
70 };
71
72 /*
73 * Local polyfill of Object.create
74
75 */
76 var create = Object.create || (function () {
77 function F() {}
78
79 return function (obj) {
80 var subtype;
81
82 F.prototype = obj;
83
84 subtype = new F();
85
86 F.prototype = null;
87
88 return subtype;
89 };
90 }())
91
92 /**
93 * CryptoJS namespace.
94 */
95 var C = {};
96
97 /**
98 * Library namespace.
99 */
100 var C_lib = C.lib = {};
101
102 /**
103 * Base object for prototypal inheritance.
104 */
105 var Base = C_lib.Base = (function () {
106
107
108 return {
109 /**
110 * Creates a new object that inherits from this object.
111 *
112 * @param {Object} overrides Properties to copy into the new object.
113 *
114 * @return {Object} The new object.
115 *
116 * @static
117 *
118 * @example
119 *
120 * var MyType = CryptoJS.lib.Base.extend({
121 * field: 'value',
122 *
123 * method: function () {
124 * }
125 * });
126 */
127 extend: function (overrides) {
128 // Spawn
129 var subtype = create(this);
130
131 // Augment
132 if (overrides) {
133 subtype.mixIn(overrides);
134 }
135
136 // Create default initializer
137 if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
138 subtype.init = function () {
139 subtype.$super.init.apply(this, arguments);
140 };
141 }
142
143 // Initializer's prototype is the subtype object
144 subtype.init.prototype = subtype;
145
146 // Reference supertype
147 subtype.$super = this;
148
149 return subtype;
150 },
151
152 /**
153 * Extends this object and runs the init method.
154 * Arguments to create() will be passed to init().
155 *
156 * @return {Object} The new object.
157 *
158 * @static
159 *
160 * @example
161 *
162 * var instance = MyType.create();
163 */
164 create: function () {
165 var instance = this.extend();
166 instance.init.apply(instance, arguments);
167
168 return instance;
169 },
170
171 /**
172 * Initializes a newly created object.
173 * Override this method to add some logic when your objects are created.
174 *
175 * @example
176 *
177 * var MyType = CryptoJS.lib.Base.extend({
178 * init: function () {
179 * // ...
180 * }
181 * });
182 */
183 init: function () {
184 },
185
186 /**
187 * Copies properties into this object.
188 *
189 * @param {Object} properties The properties to mix in.
190 *
191 * @example
192 *
193 * MyType.mixIn({
194 * field: 'value'
195 * });
196 */
197 mixIn: function (properties) {
198 for (var propertyName in properties) {
199 if (properties.hasOwnProperty(propertyName)) {
200 this[propertyName] = properties[propertyName];
201 }
202 }
203
204 // IE won't copy toString using the loop above
205 if (properties.hasOwnProperty('toString')) {
206 this.toString = properties.toString;
207 }
208 },
209
210 /**
211 * Creates a copy of this object.
212 *
213 * @return {Object} The clone.
214 *
215 * @example
216 *
217 * var clone = instance.clone();
218 */
219 clone: function () {
220 return this.init.prototype.extend(this);
221 }
222 };
223 }());
224
225 /**
226 * An array of 32-bit words.
227 *
228 * @property {Array} words The array of 32-bit words.
229 * @property {number} sigBytes The number of significant bytes in this word array.
230 */
231 var WordArray = C_lib.WordArray = Base.extend({
232 /**
233 * Initializes a newly created word array.
234 *
235 * @param {Array} words (Optional) An array of 32-bit words.
236 * @param {number} sigBytes (Optional) The number of significant bytes in the words.
237 *
238 * @example
239 *
240 * var wordArray = CryptoJS.lib.WordArray.create();
241 * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
242 * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
243 */
244 init: function (words, sigBytes) {
245 words = this.words = words || [];
246
247 if (sigBytes != undefined) {
248 this.sigBytes = sigBytes;
249 } else {
250 this.sigBytes = words.length * 4;
251 }
252 },
253
254 /**
255 * Converts this word array to a string.
256 *
257 * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
258 *
259 * @return {string} The stringified word array.
260 *
261 * @example
262 *
263 * var string = wordArray + '';
264 * var string = wordArray.toString();
265 * var string = wordArray.toString(CryptoJS.enc.Utf8);
266 */
267 toString: function (encoder) {
268 return (encoder || Hex).stringify(this);
269 },
270
271 /**
272 * Concatenates a word array to this word array.
273 *
274 * @param {WordArray} wordArray The word array to append.
275 *
276 * @return {WordArray} This word array.
277 *
278 * @example
279 *
280 * wordArray1.concat(wordArray2);
281 */
282 concat: function (wordArray) {
283 // Shortcuts
284 var thisWords = this.words;
285 var thatWords = wordArray.words;
286 var thisSigBytes = this.sigBytes;
287 var thatSigBytes = wordArray.sigBytes;
288
289 // Clamp excess bits
290 this.clamp();
291
292 // Concat
293 if (thisSigBytes % 4) {
294 // Copy one byte at a time
295 for (var i = 0; i < thatSigBytes; i++) {
296 var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
297 thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
298 }
299 } else {
300 // Copy one word at a time
301 for (var i = 0; i < thatSigBytes; i += 4) {
302 thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
303 }
304 }
305 this.sigBytes += thatSigBytes;
306
307 // Chainable
308 return this;
309 },
310
311 /**
312 * Removes insignificant bits.
313 *
314 * @example
315 *
316 * wordArray.clamp();
317 */
318 clamp: function () {
319 // Shortcuts
320 var words = this.words;
321 var sigBytes = this.sigBytes;
322
323 // Clamp
324 words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
325 words.length = Math.ceil(sigBytes / 4);
326 },
327
328 /**
329 * Creates a copy of this word array.
330 *
331 * @return {WordArray} The clone.
332 *
333 * @example
334 *
335 * var clone = wordArray.clone();
336 */
337 clone: function () {
338 var clone = Base.clone.call(this);
339 clone.words = this.words.slice(0);
340
341 return clone;
342 },
343
344 /**
345 * Creates a word array filled with random bytes.
346 *
347 * @param {number} nBytes The number of random bytes to generate.
348 *
349 * @return {WordArray} The random word array.
350 *
351 * @static
352 *
353 * @example
354 *
355 * var wordArray = CryptoJS.lib.WordArray.random(16);
356 */
357 random: function (nBytes) {
358 var words = [];
359
360 for (var i = 0; i < nBytes; i += 4) {
361 words.push(cryptoSecureRandomInt());
362 }
363
364 return new WordArray.init(words, nBytes);
365 }
366 });
367
368 /**
369 * Encoder namespace.
370 */
371 var C_enc = C.enc = {};
372
373 /**
374 * Hex encoding strategy.
375 */
376 var Hex = C_enc.Hex = {
377 /**
378 * Converts a word array to a hex string.
379 *
380 * @param {WordArray} wordArray The word array.
381 *
382 * @return {string} The hex string.
383 *
384 * @static
385 *
386 * @example
387 *
388 * var hexString = CryptoJS.enc.Hex.stringify(wordArray);
389 */
390 stringify: function (wordArray) {
391 // Shortcuts
392 var words = wordArray.words;
393 var sigBytes = wordArray.sigBytes;
394
395 // Convert
396 var hexChars = [];
397 for (var i = 0; i < sigBytes; i++) {
398 var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
399 hexChars.push((bite >>> 4).toString(16));
400 hexChars.push((bite & 0x0f).toString(16));
401 }
402
403 return hexChars.join('');
404 },
405
406 /**
407 * Converts a hex string to a word array.
408 *
409 * @param {string} hexStr The hex string.
410 *
411 * @return {WordArray} The word array.
412 *
413 * @static
414 *
415 * @example
416 *
417 * var wordArray = CryptoJS.enc.Hex.parse(hexString);
418 */
419 parse: function (hexStr) {
420 // Shortcut
421 var hexStrLength = hexStr.length;
422
423 // Convert
424 var words = [];
425 for (var i = 0; i < hexStrLength; i += 2) {
426 words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
427 }
428
429 return new WordArray.init(words, hexStrLength / 2);
430 }
431 };
432
433 /**
434 * Latin1 encoding strategy.
435 */
436 var Latin1 = C_enc.Latin1 = {
437 /**
438 * Converts a word array to a Latin1 string.
439 *
440 * @param {WordArray} wordArray The word array.
441 *
442 * @return {string} The Latin1 string.
443 *
444 * @static
445 *
446 * @example
447 *
448 * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
449 */
450 stringify: function (wordArray) {
451 // Shortcuts
452 var words = wordArray.words;
453 var sigBytes = wordArray.sigBytes;
454
455 // Convert
456 var latin1Chars = [];
457 for (var i = 0; i < sigBytes; i++) {
458 var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
459 latin1Chars.push(String.fromCharCode(bite));
460 }
461
462 return latin1Chars.join('');
463 },
464
465 /**
466 * Converts a Latin1 string to a word array.
467 *
468 * @param {string} latin1Str The Latin1 string.
469 *
470 * @return {WordArray} The word array.
471 *
472 * @static
473 *
474 * @example
475 *
476 * var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
477 */
478 parse: function (latin1Str) {
479 // Shortcut
480 var latin1StrLength = latin1Str.length;
481
482 // Convert
483 var words = [];
484 for (var i = 0; i < latin1StrLength; i++) {
485 words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
486 }
487
488 return new WordArray.init(words, latin1StrLength);
489 }
490 };
491
492 /**
493 * UTF-8 encoding strategy.
494 */
495 var Utf8 = C_enc.Utf8 = {
496 /**
497 * Converts a word array to a UTF-8 string.
498 *
499 * @param {WordArray} wordArray The word array.
500 *
501 * @return {string} The UTF-8 string.
502 *
503 * @static
504 *
505 * @example
506 *
507 * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
508 */
509 stringify: function (wordArray) {
510 try {
511 return decodeURIComponent(escape(Latin1.stringify(wordArray)));
512 } catch (e) {
513 throw new Error('Malformed UTF-8 data');
514 }
515 },
516
517 /**
518 * Converts a UTF-8 string to a word array.
519 *
520 * @param {string} utf8Str The UTF-8 string.
521 *
522 * @return {WordArray} The word array.
523 *
524 * @static
525 *
526 * @example
527 *
528 * var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
529 */
530 parse: function (utf8Str) {
531 return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
532 }
533 };
534
535 /**
536 * Abstract buffered block algorithm template.
537 *
538 * The property blockSize must be implemented in a concrete subtype.
539 *
540 * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
541 */
542 var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
543 /**
544 * Resets this block algorithm's data buffer to its initial state.
545 *
546 * @example
547 *
548 * bufferedBlockAlgorithm.reset();
549 */
550 reset: function () {
551 // Initial values
552 this._data = new WordArray.init();
553 this._nDataBytes = 0;
554 },
555
556 /**
557 * Adds new data to this block algorithm's buffer.
558 *
559 * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
560 *
561 * @example
562 *
563 * bufferedBlockAlgorithm._append('data');
564 * bufferedBlockAlgorithm._append(wordArray);
565 */
566 _append: function (data) {
567 // Convert string to WordArray, else assume WordArray already
568 if (typeof data == 'string') {
569 data = Utf8.parse(data);
570 }
571
572 // Append
573 this._data.concat(data);
574 this._nDataBytes += data.sigBytes;
575 },
576
577 /**
578 * Processes available data blocks.
579 *
580 * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
581 *
582 * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
583 *
584 * @return {WordArray} The processed data.
585 *
586 * @example
587 *
588 * var processedData = bufferedBlockAlgorithm._process();
589 * var processedData = bufferedBlockAlgorithm._process(!!'flush');
590 */
591 _process: function (doFlush) {
592 var processedWords;
593
594 // Shortcuts
595 var data = this._data;
596 var dataWords = data.words;
597 var dataSigBytes = data.sigBytes;
598 var blockSize = this.blockSize;
599 var blockSizeBytes = blockSize * 4;
600
601 // Count blocks ready
602 var nBlocksReady = dataSigBytes / blockSizeBytes;
603 if (doFlush) {
604 // Round up to include partial blocks
605 nBlocksReady = Math.ceil(nBlocksReady);
606 } else {
607 // Round down to include only full blocks,
608 // less the number of blocks that must remain in the buffer
609 nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
610 }
611
612 // Count words ready
613 var nWordsReady = nBlocksReady * blockSize;
614
615 // Count bytes ready
616 var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
617
618 // Process blocks
619 if (nWordsReady) {
620 for (var offset = 0; offset < nWordsReady; offset += blockSize) {
621 // Perform concrete-algorithm logic
622 this._doProcessBlock(dataWords, offset);
623 }
624
625 // Remove processed words
626 processedWords = dataWords.splice(0, nWordsReady);
627 data.sigBytes -= nBytesReady;
628 }
629
630 // Return processed words
631 return new WordArray.init(processedWords, nBytesReady);
632 },
633
634 /**
635 * Creates a copy of this object.
636 *
637 * @return {Object} The clone.
638 *
639 * @example
640 *
641 * var clone = bufferedBlockAlgorithm.clone();
642 */
643 clone: function () {
644 var clone = Base.clone.call(this);
645 clone._data = this._data.clone();
646
647 return clone;
648 },
649
650 _minBufferSize: 0
651 });
652
653 /**
654 * Abstract hasher template.
655 *
656 * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
657 */
658 var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
659 /**
660 * Configuration options.
661 */
662 cfg: Base.extend(),
663
664 /**
665 * Initializes a newly created hasher.
666 *
667 * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
668 *
669 * @example
670 *
671 * var hasher = CryptoJS.algo.SHA256.create();
672 */
673 init: function (cfg) {
674 // Apply config defaults
675 this.cfg = this.cfg.extend(cfg);
676
677 // Set initial values
678 this.reset();
679 },
680
681 /**
682 * Resets this hasher to its initial state.
683 *
684 * @example
685 *
686 * hasher.reset();
687 */
688 reset: function () {
689 // Reset data buffer
690 BufferedBlockAlgorithm.reset.call(this);
691
692 // Perform concrete-hasher logic
693 this._doReset();
694 },
695
696 /**
697 * Updates this hasher with a message.
698 *
699 * @param {WordArray|string} messageUpdate The message to append.
700 *
701 * @return {Hasher} This hasher.
702 *
703 * @example
704 *
705 * hasher.update('message');
706 * hasher.update(wordArray);
707 */
708 update: function (messageUpdate) {
709 // Append
710 this._append(messageUpdate);
711
712 // Update the hash
713 this._process();
714
715 // Chainable
716 return this;
717 },
718
719 /**
720 * Finalizes the hash computation.
721 * Note that the finalize operation is effectively a destructive, read-once operation.
722 *
723 * @param {WordArray|string} messageUpdate (Optional) A final message update.
724 *
725 * @return {WordArray} The hash.
726 *
727 * @example
728 *
729 * var hash = hasher.finalize();
730 * var hash = hasher.finalize('message');
731 * var hash = hasher.finalize(wordArray);
732 */
733 finalize: function (messageUpdate) {
734 // Final message update
735 if (messageUpdate) {
736 this._append(messageUpdate);
737 }
738
739 // Perform concrete-hasher logic
740 var hash = this._doFinalize();
741
742 return hash;
743 },
744
745 blockSize: 512/32,
746
747 /**
748 * Creates a shortcut function to a hasher's object interface.
749 *
750 * @param {Hasher} hasher The hasher to create a helper for.
751 *
752 * @return {Function} The shortcut function.
753 *
754 * @static
755 *
756 * @example
757 *
758 * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
759 */
760 _createHelper: function (hasher) {
761 return function (message, cfg) {
762 return new hasher.init(cfg).finalize(message);
763 };
764 },
765
766 /**
767 * Creates a shortcut function to the HMAC's object interface.
768 *
769 * @param {Hasher} hasher The hasher to use in this HMAC helper.
770 *
771 * @return {Function} The shortcut function.
772 *
773 * @static
774 *
775 * @example
776 *
777 * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
778 */
779 _createHmacHelper: function (hasher) {
780 return function (message, key) {
781 return new C_algo.HMAC.init(hasher, key).finalize(message);
782 };
783 }
784 });
785
786 /**
787 * Algorithm namespace.
788 */
789 var C_algo = C.algo = {};
790
791 return C;
792 }(Math));
793
794
795 return CryptoJS;
796
797}));
\No newline at end of file