UNPKG

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