微信小程序AES加密(ECB模式)以及(CBC模式)


微信小程序二次改造,這其中就用到了之前從未用到過的aes加密,MD5加密。在這里 我只做aes加密的介紹與具體寫法;

想詳細學aes加密的可以百度,一大堆,就不啰嗦了

一、AES加密的倆種模式 

 1.ECB模式(不需要初始向量iv 、AES加密用的key)

  第一步:在一個公共文件夾引入下面aes源碼;可以直接復制下面的代碼

   1   /*globals window, global, require*/
   2 
   3   /**
   4    * CryptoJS core components.
   5    */
   6   var CryptoJS = CryptoJS || (function(Math, undefined) {
   7 
   8     var crypto;
   9 
  10     // Native crypto from window (Browser)
  11     if (typeof window !== 'undefined' && window.crypto) {
  12       crypto = window.crypto;
  13     }
  14 
  15     // Native (experimental IE 11) crypto from window (Browser)
  16     if (!crypto && typeof window !== 'undefined' && window.msCrypto) {
  17       crypto = window.msCrypto;
  18     }
  19 
  20     // Native crypto from global (NodeJS)
  21     if (!crypto && typeof global !== 'undefined' && global.crypto) {
  22       crypto = global.crypto;
  23     }
  24 
  25     // Native crypto import via require (NodeJS)
  26     if (!crypto && typeof require === 'function') {
  27       try {
  28         crypto = require('crypto');
  29       } catch (err) {}
  30     }
  31 
  32     /*
  33      * Cryptographically secure pseudorandom number generator
  34      *
  35      * As Math.random() is cryptographically not safe to use
  36      */
  37     var cryptoSecureRandomInt = function() {
  38       if (crypto) {
  39         // Use getRandomValues method (Browser)
  40         if (typeof crypto.getRandomValues === 'function') {
  41           try {
  42             return crypto.getRandomValues(new Uint32Array(1))[0];
  43           } catch (err) {}
  44         }
  45 
  46         // Use randomBytes method (NodeJS)
  47         if (typeof crypto.randomBytes === 'function') {
  48           try {
  49             return crypto.randomBytes(4).readInt32LE();
  50           } catch (err) {}
  51         }
  52       }
  53 
  54       throw new Error('Native crypto module could not be used to get secure random number.');
  55     };
  56 
  57     /*
  58      * Local polyfill of Object.create
  59 
  60      */
  61     var create = Object.create || (function() {
  62       function F() {}
  63 
  64       return function(obj) {
  65         var subtype;
  66 
  67         F.prototype = obj;
  68 
  69         subtype = new F();
  70 
  71         F.prototype = null;
  72 
  73         return subtype;
  74       };
  75     }())
  76 
  77     /**
  78      * CryptoJS namespace.
  79      */
  80     var C = {};
  81 
  82     /**
  83      * Library namespace.
  84      */
  85     var C_lib = C.lib = {};
  86 
  87     /**
  88      * Base object for prototypal inheritance.
  89      */
  90     var Base = C_lib.Base = (function() {
  91 
  92 
  93       return {
  94         /**
  95          * Creates a new object that inherits from this object.
  96          *
  97          * @param {Object} overrides Properties to copy into the new object.
  98          *
  99          * @return {Object} The new object.
 100          *
 101          * @static
 102          *
 103          * @example
 104          *
 105          *     var MyType = CryptoJS.lib.Base.extend({
 106          *         field: 'value',
 107          *
 108          *         method: function () {
 109          *         }
 110          *     });
 111          */
 112         extend: function(overrides) {
 113           // Spawn
 114           var subtype = create(this);
 115 
 116           // Augment
 117           if (overrides) {
 118             subtype.mixIn(overrides);
 119           }
 120 
 121           // Create default initializer
 122           if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
 123             subtype.init = function() {
 124               subtype.$super.init.apply(this, arguments);
 125             };
 126           }
 127 
 128           // Initializer's prototype is the subtype object
 129           subtype.init.prototype = subtype;
 130 
 131           // Reference supertype
 132           subtype.$super = this;
 133 
 134           return subtype;
 135         },
 136 
 137         /**
 138          * Extends this object and runs the init method.
 139          * Arguments to create() will be passed to init().
 140          *
 141          * @return {Object} The new object.
 142          *
 143          * @static
 144          *
 145          * @example
 146          *
 147          *     var instance = MyType.create();
 148          */
 149         create: function() {
 150           var instance = this.extend();
 151           instance.init.apply(instance, arguments);
 152 
 153           return instance;
 154         },
 155 
 156         /**
 157          * Initializes a newly created object.
 158          * Override this method to add some logic when your objects are created.
 159          *
 160          * @example
 161          *
 162          *     var MyType = CryptoJS.lib.Base.extend({
 163          *         init: function () {
 164          *             // ...
 165          *         }
 166          *     });
 167          */
 168         init: function() {},
 169 
 170         /**
 171          * Copies properties into this object.
 172          *
 173          * @param {Object} properties The properties to mix in.
 174          *
 175          * @example
 176          *
 177          *     MyType.mixIn({
 178          *         field: 'value'
 179          *     });
 180          */
 181         mixIn: function(properties) {
 182           for (var propertyName in properties) {
 183             if (properties.hasOwnProperty(propertyName)) {
 184               this[propertyName] = properties[propertyName];
 185             }
 186           }
 187 
 188           // IE won't copy toString using the loop above
 189           if (properties.hasOwnProperty('toString')) {
 190             this.toString = properties.toString;
 191           }
 192         },
 193 
 194         /**
 195          * Creates a copy of this object.
 196          *
 197          * @return {Object} The clone.
 198          *
 199          * @example
 200          *
 201          *     var clone = instance.clone();
 202          */
 203         clone: function() {
 204           return this.init.prototype.extend(this);
 205         }
 206       };
 207     }());
 208 
 209     /**
 210      * An array of 32-bit words.
 211      *
 212      * @property {Array} words The array of 32-bit words.
 213      * @property {number} sigBytes The number of significant bytes in this word array.
 214      */
 215     var WordArray = C_lib.WordArray = Base.extend({
 216       /**
 217        * Initializes a newly created word array.
 218        *
 219        * @param {Array} words (Optional) An array of 32-bit words.
 220        * @param {number} sigBytes (Optional) The number of significant bytes in the words.
 221        *
 222        * @example
 223        *
 224        *     var wordArray = CryptoJS.lib.WordArray.create();
 225        *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
 226        *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
 227        */
 228       init: function(words, sigBytes) {
 229         words = this.words = words || [];
 230 
 231         if (sigBytes != undefined) {
 232           this.sigBytes = sigBytes;
 233         } else {
 234           this.sigBytes = words.length * 4;
 235         }
 236       },
 237 
 238       /**
 239        * Converts this word array to a string.
 240        *
 241        * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
 242        *
 243        * @return {string} The stringified word array.
 244        *
 245        * @example
 246        *
 247        *     var string = wordArray + '';
 248        *     var string = wordArray.toString();
 249        *     var string = wordArray.toString(CryptoJS.enc.Utf8);
 250        */
 251       toString: function(encoder) {
 252         return (encoder || Hex).stringify(this);
 253       },
 254 
 255       /**
 256        * Concatenates a word array to this word array.
 257        *
 258        * @param {WordArray} wordArray The word array to append.
 259        *
 260        * @return {WordArray} This word array.
 261        *
 262        * @example
 263        *
 264        *     wordArray1.concat(wordArray2);
 265        */
 266       concat: function(wordArray) {
 267         // Shortcuts
 268         var thisWords = this.words;
 269         var thatWords = wordArray.words;
 270         var thisSigBytes = this.sigBytes;
 271         var thatSigBytes = wordArray.sigBytes;
 272 
 273         // Clamp excess bits
 274         this.clamp();
 275 
 276         // Concat
 277         if (thisSigBytes % 4) {
 278           // Copy one byte at a time
 279           for (var i = 0; i < thatSigBytes; i++) {
 280             var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
 281             thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
 282           }
 283         } else {
 284           // Copy one word at a time
 285           for (var i = 0; i < thatSigBytes; i += 4) {
 286             thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
 287           }
 288         }
 289         this.sigBytes += thatSigBytes;
 290 
 291         // Chainable
 292         return this;
 293       },
 294 
 295       /**
 296        * Removes insignificant bits.
 297        *
 298        * @example
 299        *
 300        *     wordArray.clamp();
 301        */
 302       clamp: function() {
 303         // Shortcuts
 304         var words = this.words;
 305         var sigBytes = this.sigBytes;
 306 
 307         // Clamp
 308         words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
 309         words.length = Math.ceil(sigBytes / 4);
 310       },
 311 
 312       /**
 313        * Creates a copy of this word array.
 314        *
 315        * @return {WordArray} The clone.
 316        *
 317        * @example
 318        *
 319        *     var clone = wordArray.clone();
 320        */
 321       clone: function() {
 322         var clone = Base.clone.call(this);
 323         clone.words = this.words.slice(0);
 324 
 325         return clone;
 326       },
 327 
 328       /**
 329        * Creates a word array filled with random bytes.
 330        *
 331        * @param {number} nBytes The number of random bytes to generate.
 332        *
 333        * @return {WordArray} The random word array.
 334        *
 335        * @static
 336        *
 337        * @example
 338        *
 339        *     var wordArray = CryptoJS.lib.WordArray.random(16);
 340        */
 341       random: function(nBytes) {
 342         var words = [];
 343 
 344         for (var i = 0; i < nBytes; i += 4) {
 345           words.push(cryptoSecureRandomInt());
 346         }
 347 
 348         return new WordArray.init(words, nBytes);
 349       }
 350     });
 351 
 352     /**
 353      * Encoder namespace.
 354      */
 355     var C_enc = C.enc = {};
 356 
 357     /**
 358      * Hex encoding strategy.
 359      */
 360     var Hex = C_enc.Hex = {
 361       /**
 362        * Converts a word array to a hex string.
 363        *
 364        * @param {WordArray} wordArray The word array.
 365        *
 366        * @return {string} The hex string.
 367        *
 368        * @static
 369        *
 370        * @example
 371        *
 372        *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);
 373        */
 374       stringify: function(wordArray) {
 375         // Shortcuts
 376         var words = wordArray.words;
 377         var sigBytes = wordArray.sigBytes;
 378 
 379         // Convert
 380         var hexChars = [];
 381         for (var i = 0; i < sigBytes; i++) {
 382           var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
 383           hexChars.push((bite >>> 4).toString(16));
 384           hexChars.push((bite & 0x0f).toString(16));
 385         }
 386 
 387         return hexChars.join('');
 388       },
 389 
 390       /**
 391        * Converts a hex string to a word array.
 392        *
 393        * @param {string} hexStr The hex string.
 394        *
 395        * @return {WordArray} The word array.
 396        *
 397        * @static
 398        *
 399        * @example
 400        *
 401        *     var wordArray = CryptoJS.enc.Hex.parse(hexString);
 402        */
 403       parse: function(hexStr) {
 404         // Shortcut
 405         var hexStrLength = hexStr.length;
 406 
 407         // Convert
 408         var words = [];
 409         for (var i = 0; i < hexStrLength; i += 2) {
 410           words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
 411         }
 412 
 413         return new WordArray.init(words, hexStrLength / 2);
 414       }
 415     };
 416 
 417     /**
 418      * Latin1 encoding strategy.
 419      */
 420     var Latin1 = C_enc.Latin1 = {
 421       /**
 422        * Converts a word array to a Latin1 string.
 423        *
 424        * @param {WordArray} wordArray The word array.
 425        *
 426        * @return {string} The Latin1 string.
 427        *
 428        * @static
 429        *
 430        * @example
 431        *
 432        *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
 433        */
 434       stringify: function(wordArray) {
 435         // Shortcuts
 436         var words = wordArray.words;
 437         var sigBytes = wordArray.sigBytes;
 438 
 439         // Convert
 440         var latin1Chars = [];
 441         for (var i = 0; i < sigBytes; i++) {
 442           var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
 443           latin1Chars.push(String.fromCharCode(bite));
 444         }
 445 
 446         return latin1Chars.join('');
 447       },
 448 
 449       /**
 450        * Converts a Latin1 string to a word array.
 451        *
 452        * @param {string} latin1Str The Latin1 string.
 453        *
 454        * @return {WordArray} The word array.
 455        *
 456        * @static
 457        *
 458        * @example
 459        *
 460        *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
 461        */
 462       parse: function(latin1Str) {
 463         // Shortcut
 464         var latin1StrLength = latin1Str.length;
 465 
 466         // Convert
 467         var words = [];
 468         for (var i = 0; i < latin1StrLength; i++) {
 469           words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
 470         }
 471 
 472         return new WordArray.init(words, latin1StrLength);
 473       }
 474     };
 475 
 476     /**
 477      * UTF-8 encoding strategy.
 478      */
 479     var Utf8 = C_enc.Utf8 = {
 480       /**
 481        * Converts a word array to a UTF-8 string.
 482        *
 483        * @param {WordArray} wordArray The word array.
 484        *
 485        * @return {string} The UTF-8 string.
 486        *
 487        * @static
 488        *
 489        * @example
 490        *
 491        *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
 492        */
 493       stringify: function(wordArray) {
 494         try {
 495           return decodeURIComponent(escape(Latin1.stringify(wordArray)));
 496         } catch (e) {
 497           throw new Error('Malformed UTF-8 data');
 498         }
 499       },
 500 
 501       /**
 502        * Converts a UTF-8 string to a word array.
 503        *
 504        * @param {string} utf8Str The UTF-8 string.
 505        *
 506        * @return {WordArray} The word array.
 507        *
 508        * @static
 509        *
 510        * @example
 511        *
 512        *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
 513        */
 514       parse: function(utf8Str) {
 515         return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
 516       }
 517     };
 518 
 519     /**
 520      * Abstract buffered block algorithm template.
 521      *
 522      * The property blockSize must be implemented in a concrete subtype.
 523      *
 524      * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
 525      */
 526     var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
 527       /**
 528        * Resets this block algorithm's data buffer to its initial state.
 529        *
 530        * @example
 531        *
 532        *     bufferedBlockAlgorithm.reset();
 533        */
 534       reset: function() {
 535         // Initial values
 536         this._data = new WordArray.init();
 537         this._nDataBytes = 0;
 538       },
 539 
 540       /**
 541        * Adds new data to this block algorithm's buffer.
 542        *
 543        * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
 544        *
 545        * @example
 546        *
 547        *     bufferedBlockAlgorithm._append('data');
 548        *     bufferedBlockAlgorithm._append(wordArray);
 549        */
 550       _append: function(data) {
 551         // Convert string to WordArray, else assume WordArray already
 552         if (typeof data == 'string') {
 553           data = Utf8.parse(data);
 554         }
 555 
 556         // Append
 557         this._data.concat(data);
 558         this._nDataBytes += data.sigBytes;
 559       },
 560 
 561       /**
 562        * Processes available data blocks.
 563        *
 564        * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
 565        *
 566        * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
 567        *
 568        * @return {WordArray} The processed data.
 569        *
 570        * @example
 571        *
 572        *     var processedData = bufferedBlockAlgorithm._process();
 573        *     var processedData = bufferedBlockAlgorithm._process(!!'flush');
 574        */
 575       _process: function(doFlush) {
 576         var processedWords;
 577 
 578         // Shortcuts
 579         var data = this._data;
 580         var dataWords = data.words;
 581         var dataSigBytes = data.sigBytes;
 582         var blockSize = this.blockSize;
 583         var blockSizeBytes = blockSize * 4;
 584 
 585         // Count blocks ready
 586         var nBlocksReady = dataSigBytes / blockSizeBytes;
 587         if (doFlush) {
 588           // Round up to include partial blocks
 589           nBlocksReady = Math.ceil(nBlocksReady);
 590         } else {
 591           // Round down to include only full blocks,
 592           // less the number of blocks that must remain in the buffer
 593           nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
 594         }
 595 
 596         // Count words ready
 597         var nWordsReady = nBlocksReady * blockSize;
 598 
 599         // Count bytes ready
 600         var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
 601 
 602         // Process blocks
 603         if (nWordsReady) {
 604           for (var offset = 0; offset < nWordsReady; offset += blockSize) {
 605             // Perform concrete-algorithm logic
 606             this._doProcessBlock(dataWords, offset);
 607           }
 608 
 609           // Remove processed words
 610           processedWords = dataWords.splice(0, nWordsReady);
 611           data.sigBytes -= nBytesReady;
 612         }
 613 
 614         // Return processed words
 615         return new WordArray.init(processedWords, nBytesReady);
 616       },
 617 
 618       /**
 619        * Creates a copy of this object.
 620        *
 621        * @return {Object} The clone.
 622        *
 623        * @example
 624        *
 625        *     var clone = bufferedBlockAlgorithm.clone();
 626        */
 627       clone: function() {
 628         var clone = Base.clone.call(this);
 629         clone._data = this._data.clone();
 630 
 631         return clone;
 632       },
 633 
 634       _minBufferSize: 0
 635     });
 636 
 637     /**
 638      * Abstract hasher template.
 639      *
 640      * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
 641      */
 642     var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
 643       /**
 644        * Configuration options.
 645        */
 646       cfg: Base.extend(),
 647 
 648       /**
 649        * Initializes a newly created hasher.
 650        *
 651        * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
 652        *
 653        * @example
 654        *
 655        *     var hasher = CryptoJS.algo.SHA256.create();
 656        */
 657       init: function(cfg) {
 658         // Apply config defaults
 659         this.cfg = this.cfg.extend(cfg);
 660 
 661         // Set initial values
 662         this.reset();
 663       },
 664 
 665       /**
 666        * Resets this hasher to its initial state.
 667        *
 668        * @example
 669        *
 670        *     hasher.reset();
 671        */
 672       reset: function() {
 673         // Reset data buffer
 674         BufferedBlockAlgorithm.reset.call(this);
 675 
 676         // Perform concrete-hasher logic
 677         this._doReset();
 678       },
 679 
 680       /**
 681        * Updates this hasher with a message.
 682        *
 683        * @param {WordArray|string} messageUpdate The message to append.
 684        *
 685        * @return {Hasher} This hasher.
 686        *
 687        * @example
 688        *
 689        *     hasher.update('message');
 690        *     hasher.update(wordArray);
 691        */
 692       update: function(messageUpdate) {
 693         // Append
 694         this._append(messageUpdate);
 695 
 696         // Update the hash
 697         this._process();
 698 
 699         // Chainable
 700         return this;
 701       },
 702 
 703       /**
 704        * Finalizes the hash computation.
 705        * Note that the finalize operation is effectively a destructive, read-once operation.
 706        *
 707        * @param {WordArray|string} messageUpdate (Optional) A final message update.
 708        *
 709        * @return {WordArray} The hash.
 710        *
 711        * @example
 712        *
 713        *     var hash = hasher.finalize();
 714        *     var hash = hasher.finalize('message');
 715        *     var hash = hasher.finalize(wordArray);
 716        */
 717       finalize: function(messageUpdate) {
 718         // Final message update
 719         if (messageUpdate) {
 720           this._append(messageUpdate);
 721         }
 722 
 723         // Perform concrete-hasher logic
 724         var hash = this._doFinalize();
 725 
 726         return hash;
 727       },
 728 
 729       blockSize: 512 / 32,
 730 
 731       /**
 732        * Creates a shortcut function to a hasher's object interface.
 733        *
 734        * @param {Hasher} hasher The hasher to create a helper for.
 735        *
 736        * @return {Function} The shortcut function.
 737        *
 738        * @static
 739        *
 740        * @example
 741        *
 742        *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
 743        */
 744       _createHelper: function(hasher) {
 745         return function(message, cfg) {
 746           return new hasher.init(cfg).finalize(message);
 747         };
 748       },
 749 
 750       /**
 751        * Creates a shortcut function to the HMAC's object interface.
 752        *
 753        * @param {Hasher} hasher The hasher to use in this HMAC helper.
 754        *
 755        * @return {Function} The shortcut function.
 756        *
 757        * @static
 758        *
 759        * @example
 760        *
 761        *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
 762        */
 763       _createHmacHelper: function(hasher) {
 764         return function(message, key) {
 765           return new C_algo.HMAC.init(hasher, key).finalize(message);
 766         };
 767       }
 768     });
 769 
 770     /**
 771      * Algorithm namespace.
 772      */
 773     var C_algo = C.algo = {};
 774 
 775     return C;
 776   }(Math));
 777 
 778 
 779   (function() {
 780     // Shortcuts
 781     var C = CryptoJS;
 782     var C_lib = C.lib;
 783     var WordArray = C_lib.WordArray;
 784     var C_enc = C.enc;
 785 
 786     /**
 787      * Base64 encoding strategy.
 788      */
 789     var Base64 = C_enc.Base64 = {
 790       /**
 791        * Converts a word array to a Base64 string.
 792        *
 793        * @param {WordArray} wordArray The word array.
 794        *
 795        * @return {string} The Base64 string.
 796        *
 797        * @static
 798        *
 799        * @example
 800        *
 801        *     var base64String = CryptoJS.enc.Base64.stringify(wordArray);
 802        */
 803       stringify: function(wordArray) {
 804         // Shortcuts
 805         var words = wordArray.words;
 806         var sigBytes = wordArray.sigBytes;
 807         var map = this._map;
 808 
 809         // Clamp excess bits
 810         wordArray.clamp();
 811 
 812         // Convert
 813         var base64Chars = [];
 814         for (var i = 0; i < sigBytes; i += 3) {
 815           var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
 816           var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
 817           var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
 818 
 819           var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
 820 
 821           for (var j = 0;
 822             (j < 4) && (i + j * 0.75 < sigBytes); j++) {
 823             base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
 824           }
 825         }
 826 
 827         // Add padding
 828         var paddingChar = map.charAt(64);
 829         if (paddingChar) {
 830           while (base64Chars.length % 4) {
 831             base64Chars.push(paddingChar);
 832           }
 833         }
 834 
 835         return base64Chars.join('');
 836       },
 837 
 838       /**
 839        * Converts a Base64 string to a word array.
 840        *
 841        * @param {string} base64Str The Base64 string.
 842        *
 843        * @return {WordArray} The word array.
 844        *
 845        * @static
 846        *
 847        * @example
 848        *
 849        *     var wordArray = CryptoJS.enc.Base64.parse(base64String);
 850        */
 851       parse: function(base64Str) {
 852         // Shortcuts
 853         var base64StrLength = base64Str.length;
 854         var map = this._map;
 855         var reverseMap = this._reverseMap;
 856 
 857         if (!reverseMap) {
 858           reverseMap = this._reverseMap = [];
 859           for (var j = 0; j < map.length; j++) {
 860             reverseMap[map.charCodeAt(j)] = j;
 861           }
 862         }
 863 
 864         // Ignore padding
 865         var paddingChar = map.charAt(64);
 866         if (paddingChar) {
 867           var paddingIndex = base64Str.indexOf(paddingChar);
 868           if (paddingIndex !== -1) {
 869             base64StrLength = paddingIndex;
 870           }
 871         }
 872 
 873         // Convert
 874         return parseLoop(base64Str, base64StrLength, reverseMap);
 875 
 876       },
 877 
 878       _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
 879     };
 880 
 881     function parseLoop(base64Str, base64StrLength, reverseMap) {
 882       var words = [];
 883       var nBytes = 0;
 884       for (var i = 0; i < base64StrLength; i++) {
 885         if (i % 4) {
 886           var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);
 887           var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);
 888           var bitsCombined = bits1 | bits2;
 889           words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8);
 890           nBytes++;
 891         }
 892       }
 893       return WordArray.create(words, nBytes);
 894     }
 895   }());
 896 
 897 
 898   (function(Math) {
 899     // Shortcuts
 900     var C = CryptoJS;
 901     var C_lib = C.lib;
 902     var WordArray = C_lib.WordArray;
 903     var Hasher = C_lib.Hasher;
 904     var C_algo = C.algo;
 905 
 906     // Constants table
 907     var T = [];
 908 
 909     // Compute constants
 910     (function() {
 911       for (var i = 0; i < 64; i++) {
 912         T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;
 913       }
 914     }());
 915 
 916     /**
 917      * MD5 hash algorithm.
 918      */
 919     var MD5 = C_algo.MD5 = Hasher.extend({
 920       _doReset: function() {
 921         this._hash = new WordArray.init([
 922           0x67452301, 0xefcdab89,
 923           0x98badcfe, 0x10325476
 924         ]);
 925       },
 926 
 927       _doProcessBlock: function(M, offset) {
 928         // Swap endian
 929         for (var i = 0; i < 16; i++) {
 930           // Shortcuts
 931           var offset_i = offset + i;
 932           var M_offset_i = M[offset_i];
 933 
 934           M[offset_i] = (
 935             (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
 936             (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
 937           );
 938         }
 939 
 940         // Shortcuts
 941         var H = this._hash.words;
 942 
 943         var M_offset_0 = M[offset + 0];
 944         var M_offset_1 = M[offset + 1];
 945         var M_offset_2 = M[offset + 2];
 946         var M_offset_3 = M[offset + 3];
 947         var M_offset_4 = M[offset + 4];
 948         var M_offset_5 = M[offset + 5];
 949         var M_offset_6 = M[offset + 6];
 950         var M_offset_7 = M[offset + 7];
 951         var M_offset_8 = M[offset + 8];
 952         var M_offset_9 = M[offset + 9];
 953         var M_offset_10 = M[offset + 10];
 954         var M_offset_11 = M[offset + 11];
 955         var M_offset_12 = M[offset + 12];
 956         var M_offset_13 = M[offset + 13];
 957         var M_offset_14 = M[offset + 14];
 958         var M_offset_15 = M[offset + 15];
 959 
 960         // Working varialbes
 961         var a = H[0];
 962         var b = H[1];
 963         var c = H[2];
 964         var d = H[3];
 965 
 966         // Computation
 967         a = FF(a, b, c, d, M_offset_0, 7, T[0]);
 968         d = FF(d, a, b, c, M_offset_1, 12, T[1]);
 969         c = FF(c, d, a, b, M_offset_2, 17, T[2]);
 970         b = FF(b, c, d, a, M_offset_3, 22, T[3]);
 971         a = FF(a, b, c, d, M_offset_4, 7, T[4]);
 972         d = FF(d, a, b, c, M_offset_5, 12, T[5]);
 973         c = FF(c, d, a, b, M_offset_6, 17, T[6]);
 974         b = FF(b, c, d, a, M_offset_7, 22, T[7]);
 975         a = FF(a, b, c, d, M_offset_8, 7, T[8]);
 976         d = FF(d, a, b, c, M_offset_9, 12, T[9]);
 977         c = FF(c, d, a, b, M_offset_10, 17, T[10]);
 978         b = FF(b, c, d, a, M_offset_11, 22, T[11]);
 979         a = FF(a, b, c, d, M_offset_12, 7, T[12]);
 980         d = FF(d, a, b, c, M_offset_13, 12, T[13]);
 981         c = FF(c, d, a, b, M_offset_14, 17, T[14]);
 982         b = FF(b, c, d, a, M_offset_15, 22, T[15]);
 983 
 984         a = GG(a, b, c, d, M_offset_1, 5, T[16]);
 985         d = GG(d, a, b, c, M_offset_6, 9, T[17]);
 986         c = GG(c, d, a, b, M_offset_11, 14, T[18]);
 987         b = GG(b, c, d, a, M_offset_0, 20, T[19]);
 988         a = GG(a, b, c, d, M_offset_5, 5, T[20]);
 989         d = GG(d, a, b, c, M_offset_10, 9, T[21]);
 990         c = GG(c, d, a, b, M_offset_15, 14, T[22]);
 991         b = GG(b, c, d, a, M_offset_4, 20, T[23]);
 992         a = GG(a, b, c, d, M_offset_9, 5, T[24]);
 993         d = GG(d, a, b, c, M_offset_14, 9, T[25]);
 994         c = GG(c, d, a, b, M_offset_3, 14, T[26]);
 995         b = GG(b, c, d, a, M_offset_8, 20, T[27]);
 996         a = GG(a, b, c, d, M_offset_13, 5, T[28]);
 997         d = GG(d, a, b, c, M_offset_2, 9, T[29]);
 998         c = GG(c, d, a, b, M_offset_7, 14, T[30]);
 999         b = GG(b, c, d, a, M_offset_12, 20, T[31]);
1000 
1001         a = HH(a, b, c, d, M_offset_5, 4, T[32]);
1002         d = HH(d, a, b, c, M_offset_8, 11, T[33]);
1003         c = HH(c, d, a, b, M_offset_11, 16, T[34]);
1004         b = HH(b, c, d, a, M_offset_14, 23, T[35]);
1005         a = HH(a, b, c, d, M_offset_1, 4, T[36]);
1006         d = HH(d, a, b, c, M_offset_4, 11, T[37]);
1007         c = HH(c, d, a, b, M_offset_7, 16, T[38]);
1008         b = HH(b, c, d, a, M_offset_10, 23, T[39]);
1009         a = HH(a, b, c, d, M_offset_13, 4, T[40]);
1010         d = HH(d, a, b, c, M_offset_0, 11, T[41]);
1011         c = HH(c, d, a, b, M_offset_3, 16, T[42]);
1012         b = HH(b, c, d, a, M_offset_6, 23, T[43]);
1013         a = HH(a, b, c, d, M_offset_9, 4, T[44]);
1014         d = HH(d, a, b, c, M_offset_12, 11, T[45]);
1015         c = HH(c, d, a, b, M_offset_15, 16, T[46]);
1016         b = HH(b, c, d, a, M_offset_2, 23, T[47]);
1017 
1018         a = II(a, b, c, d, M_offset_0, 6, T[48]);
1019         d = II(d, a, b, c, M_offset_7, 10, T[49]);
1020         c = II(c, d, a, b, M_offset_14, 15, T[50]);
1021         b = II(b, c, d, a, M_offset_5, 21, T[51]);
1022         a = II(a, b, c, d, M_offset_12, 6, T[52]);
1023         d = II(d, a, b, c, M_offset_3, 10, T[53]);
1024         c = II(c, d, a, b, M_offset_10, 15, T[54]);
1025         b = II(b, c, d, a, M_offset_1, 21, T[55]);
1026         a = II(a, b, c, d, M_offset_8, 6, T[56]);
1027         d = II(d, a, b, c, M_offset_15, 10, T[57]);
1028         c = II(c, d, a, b, M_offset_6, 15, T[58]);
1029         b = II(b, c, d, a, M_offset_13, 21, T[59]);
1030         a = II(a, b, c, d, M_offset_4, 6, T[60]);
1031         d = II(d, a, b, c, M_offset_11, 10, T[61]);
1032         c = II(c, d, a, b, M_offset_2, 15, T[62]);
1033         b = II(b, c, d, a, M_offset_9, 21, T[63]);
1034 
1035         // Intermediate hash value
1036         H[0] = (H[0] + a) | 0;
1037         H[1] = (H[1] + b) | 0;
1038         H[2] = (H[2] + c) | 0;
1039         H[3] = (H[3] + d) | 0;
1040       },
1041 
1042       _doFinalize: function() {
1043         // Shortcuts
1044         var data = this._data;
1045         var dataWords = data.words;
1046 
1047         var nBitsTotal = this._nDataBytes * 8;
1048         var nBitsLeft = data.sigBytes * 8;
1049 
1050         // Add padding
1051         dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
1052 
1053         var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
1054         var nBitsTotalL = nBitsTotal;
1055         dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (
1056           (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) |
1057           (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00)
1058         );
1059         dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
1060           (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) |
1061           (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00)
1062         );
1063 
1064         data.sigBytes = (dataWords.length + 1) * 4;
1065 
1066         // Hash final blocks
1067         this._process();
1068 
1069         // Shortcuts
1070         var hash = this._hash;
1071         var H = hash.words;
1072 
1073         // Swap endian
1074         for (var i = 0; i < 4; i++) {
1075           // Shortcut
1076           var H_i = H[i];
1077 
1078           H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) |
1079             (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
1080         }
1081 
1082         // Return final computed hash
1083         return hash;
1084       },
1085 
1086       clone: function() {
1087         var clone = Hasher.clone.call(this);
1088         clone._hash = this._hash.clone();
1089 
1090         return clone;
1091       }
1092     });
1093 
1094     function FF(a, b, c, d, x, s, t) {
1095       var n = a + ((b & c) | (~b & d)) + x + t;
1096       return ((n << s) | (n >>> (32 - s))) + b;
1097     }
1098 
1099     function GG(a, b, c, d, x, s, t) {
1100       var n = a + ((b & d) | (c & ~d)) + x + t;
1101       return ((n << s) | (n >>> (32 - s))) + b;
1102     }
1103 
1104     function HH(a, b, c, d, x, s, t) {
1105       var n = a + (b ^ c ^ d) + x + t;
1106       return ((n << s) | (n >>> (32 - s))) + b;
1107     }
1108 
1109     function II(a, b, c, d, x, s, t) {
1110       var n = a + (c ^ (b | ~d)) + x + t;
1111       return ((n << s) | (n >>> (32 - s))) + b;
1112     }
1113 
1114     /**
1115      * Shortcut function to the hasher's object interface.
1116      *
1117      * @param {WordArray|string} message The message to hash.
1118      *
1119      * @return {WordArray} The hash.
1120      *
1121      * @static
1122      *
1123      * @example
1124      *
1125      *     var hash = CryptoJS.MD5('message');
1126      *     var hash = CryptoJS.MD5(wordArray);
1127      */
1128     C.MD5 = Hasher._createHelper(MD5);
1129 
1130     /**
1131      * Shortcut function to the HMAC's object interface.
1132      *
1133      * @param {WordArray|string} message The message to hash.
1134      * @param {WordArray|string} key The secret key.
1135      *
1136      * @return {WordArray} The HMAC.
1137      *
1138      * @static
1139      *
1140      * @example
1141      *
1142      *     var hmac = CryptoJS.HmacMD5(message, key);
1143      */
1144     C.HmacMD5 = Hasher._createHmacHelper(MD5);
1145   }(Math));
1146 
1147 
1148   (function() {
1149     // Shortcuts
1150     var C = CryptoJS;
1151     var C_lib = C.lib;
1152     var WordArray = C_lib.WordArray;
1153     var Hasher = C_lib.Hasher;
1154     var C_algo = C.algo;
1155 
1156     // Reusable object
1157     var W = [];
1158 
1159     /**
1160      * SHA-1 hash algorithm.
1161      */
1162     var SHA1 = C_algo.SHA1 = Hasher.extend({
1163       _doReset: function() {
1164         this._hash = new WordArray.init([
1165           0x67452301, 0xefcdab89,
1166           0x98badcfe, 0x10325476,
1167           0xc3d2e1f0
1168         ]);
1169       },
1170 
1171       _doProcessBlock: function(M, offset) {
1172         // Shortcut
1173         var H = this._hash.words;
1174 
1175         // Working variables
1176         var a = H[0];
1177         var b = H[1];
1178         var c = H[2];
1179         var d = H[3];
1180         var e = H[4];
1181 
1182         // Computation
1183         for (var i = 0; i < 80; i++) {
1184           if (i < 16) {
1185             W[i] = M[offset + i] | 0;
1186           } else {
1187             var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
1188             W[i] = (n << 1) | (n >>> 31);
1189           }
1190 
1191           var t = ((a << 5) | (a >>> 27)) + e + W[i];
1192           if (i < 20) {
1193             t += ((b & c) | (~b & d)) + 0x5a827999;
1194           } else if (i < 40) {
1195             t += (b ^ c ^ d) + 0x6ed9eba1;
1196           } else if (i < 60) {
1197             t += ((b & c) | (b & d) | (c & d)) - 0x70e44324;
1198           } else /* if (i < 80) */ {
1199             t += (b ^ c ^ d) - 0x359d3e2a;
1200           }
1201 
1202           e = d;
1203           d = c;
1204           c = (b << 30) | (b >>> 2);
1205           b = a;
1206           a = t;
1207         }
1208 
1209         // Intermediate hash value
1210         H[0] = (H[0] + a) | 0;
1211         H[1] = (H[1] + b) | 0;
1212         H[2] = (H[2] + c) | 0;
1213         H[3] = (H[3] + d) | 0;
1214         H[4] = (H[4] + e) | 0;
1215       },
1216 
1217       _doFinalize: function() {
1218         // Shortcuts
1219         var data = this._data;
1220         var dataWords = data.words;
1221 
1222         var nBitsTotal = this._nDataBytes * 8;
1223         var nBitsLeft = data.sigBytes * 8;
1224 
1225         // Add padding
1226         dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
1227         dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
1228         dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
1229         data.sigBytes = dataWords.length * 4;
1230 
1231         // Hash final blocks
1232         this._process();
1233 
1234         // Return final computed hash
1235         return this._hash;
1236       },
1237 
1238       clone: function() {
1239         var clone = Hasher.clone.call(this);
1240         clone._hash = this._hash.clone();
1241 
1242         return clone;
1243       }
1244     });
1245 
1246     /**
1247      * Shortcut function to the hasher's object interface.
1248      *
1249      * @param {WordArray|string} message The message to hash.
1250      *
1251      * @return {WordArray} The hash.
1252      *
1253      * @static
1254      *
1255      * @example
1256      *
1257      *     var hash = CryptoJS.SHA1('message');
1258      *     var hash = CryptoJS.SHA1(wordArray);
1259      */
1260     C.SHA1 = Hasher._createHelper(SHA1);
1261 
1262     /**
1263      * Shortcut function to the HMAC's object interface.
1264      *
1265      * @param {WordArray|string} message The message to hash.
1266      * @param {WordArray|string} key The secret key.
1267      *
1268      * @return {WordArray} The HMAC.
1269      *
1270      * @static
1271      *
1272      * @example
1273      *
1274      *     var hmac = CryptoJS.HmacSHA1(message, key);
1275      */
1276     C.HmacSHA1 = Hasher._createHmacHelper(SHA1);
1277   }());
1278 
1279 
1280   (function(Math) {
1281     // Shortcuts
1282     var C = CryptoJS;
1283     var C_lib = C.lib;
1284     var WordArray = C_lib.WordArray;
1285     var Hasher = C_lib.Hasher;
1286     var C_algo = C.algo;
1287 
1288     // Initialization and round constants tables
1289     var H = [];
1290     var K = [];
1291 
1292     // Compute constants
1293     (function() {
1294       function isPrime(n) {
1295         var sqrtN = Math.sqrt(n);
1296         for (var factor = 2; factor <= sqrtN; factor++) {
1297           if (!(n % factor)) {
1298             return false;
1299           }
1300         }
1301 
1302         return true;
1303       }
1304 
1305       function getFractionalBits(n) {
1306         return ((n - (n | 0)) * 0x100000000) | 0;
1307       }
1308 
1309       var n = 2;
1310       var nPrime = 0;
1311       while (nPrime < 64) {
1312         if (isPrime(n)) {
1313           if (nPrime < 8) {
1314             H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));
1315           }
1316           K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));
1317 
1318           nPrime++;
1319         }
1320 
1321         n++;
1322       }
1323     }());
1324 
1325     // Reusable object
1326     var W = [];
1327 
1328     /**
1329      * SHA-256 hash algorithm.
1330      */
1331     var SHA256 = C_algo.SHA256 = Hasher.extend({
1332       _doReset: function() {
1333         this._hash = new WordArray.init(H.slice(0));
1334       },
1335 
1336       _doProcessBlock: function(M, offset) {
1337         // Shortcut
1338         var H = this._hash.words;
1339 
1340         // Working variables
1341         var a = H[0];
1342         var b = H[1];
1343         var c = H[2];
1344         var d = H[3];
1345         var e = H[4];
1346         var f = H[5];
1347         var g = H[6];
1348         var h = H[7];
1349 
1350         // Computation
1351         for (var i = 0; i < 64; i++) {
1352           if (i < 16) {
1353             W[i] = M[offset + i] | 0;
1354           } else {
1355             var gamma0x = W[i - 15];
1356             var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
1357               ((gamma0x << 14) | (gamma0x >>> 18)) ^
1358               (gamma0x >>> 3);
1359 
1360             var gamma1x = W[i - 2];
1361             var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
1362               ((gamma1x << 13) | (gamma1x >>> 19)) ^
1363               (gamma1x >>> 10);
1364 
1365             W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
1366           }
1367 
1368           var ch = (e & f) ^ (~e & g);
1369           var maj = (a & b) ^ (a & c) ^ (b & c);
1370 
1371           var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));
1372           var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25));
1373 
1374           var t1 = h + sigma1 + ch + K[i] + W[i];
1375           var t2 = sigma0 + maj;
1376 
1377           h = g;
1378           g = f;
1379           f = e;
1380           e = (d + t1) | 0;
1381           d = c;
1382           c = b;
1383           b = a;
1384           a = (t1 + t2) | 0;
1385         }
1386 
1387         // Intermediate hash value
1388         H[0] = (H[0] + a) | 0;
1389         H[1] = (H[1] + b) | 0;
1390         H[2] = (H[2] + c) | 0;
1391         H[3] = (H[3] + d) | 0;
1392         H[4] = (H[4] + e) | 0;
1393         H[5] = (H[5] + f) | 0;
1394         H[6] = (H[6] + g) | 0;
1395         H[7] = (H[7] + h) | 0;
1396       },
1397 
1398       _doFinalize: function() {
1399         // Shortcuts
1400         var data = this._data;
1401         var dataWords = data.words;
1402 
1403         var nBitsTotal = this._nDataBytes * 8;
1404         var nBitsLeft = data.sigBytes * 8;
1405 
1406         // Add padding
1407         dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
1408         dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
1409         dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
1410         data.sigBytes = dataWords.length * 4;
1411 
1412         // Hash final blocks
1413         this._process();
1414 
1415         // Return final computed hash
1416         return this._hash;
1417       },
1418 
1419       clone: function() {
1420         var clone = Hasher.clone.call(this);
1421         clone._hash = this._hash.clone();
1422 
1423         return clone;
1424       }
1425     });
1426 
1427     /**
1428      * Shortcut function to the hasher's object interface.
1429      *
1430      * @param {WordArray|string} message The message to hash.
1431      *
1432      * @return {WordArray} The hash.
1433      *
1434      * @static
1435      *
1436      * @example
1437      *
1438      *     var hash = CryptoJS.SHA256('message');
1439      *     var hash = CryptoJS.SHA256(wordArray);
1440      */
1441     C.SHA256 = Hasher._createHelper(SHA256);
1442 
1443     /**
1444      * Shortcut function to the HMAC's object interface.
1445      *
1446      * @param {WordArray|string} message The message to hash.
1447      * @param {WordArray|string} key The secret key.
1448      *
1449      * @return {WordArray} The HMAC.
1450      *
1451      * @static
1452      *
1453      * @example
1454      *
1455      *     var hmac = CryptoJS.HmacSHA256(message, key);
1456      */
1457     C.HmacSHA256 = Hasher._createHmacHelper(SHA256);
1458   }(Math));
1459 
1460 
1461   (function() {
1462     // Shortcuts
1463     var C = CryptoJS;
1464     var C_lib = C.lib;
1465     var WordArray = C_lib.WordArray;
1466     var C_enc = C.enc;
1467 
1468     /**
1469      * UTF-16 BE encoding strategy.
1470      */
1471     var Utf16BE = C_enc.Utf16 = C_enc.Utf16BE = {
1472       /**
1473        * Converts a word array to a UTF-16 BE string.
1474        *
1475        * @param {WordArray} wordArray The word array.
1476        *
1477        * @return {string} The UTF-16 BE string.
1478        *
1479        * @static
1480        *
1481        * @example
1482        *
1483        *     var utf16String = CryptoJS.enc.Utf16.stringify(wordArray);
1484        */
1485       stringify: function(wordArray) {
1486         // Shortcuts
1487         var words = wordArray.words;
1488         var sigBytes = wordArray.sigBytes;
1489 
1490         // Convert
1491         var utf16Chars = [];
1492         for (var i = 0; i < sigBytes; i += 2) {
1493           var codePoint = (words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff;
1494           utf16Chars.push(String.fromCharCode(codePoint));
1495         }
1496 
1497         return utf16Chars.join('');
1498       },
1499 
1500       /**
1501        * Converts a UTF-16 BE string to a word array.
1502        *
1503        * @param {string} utf16Str The UTF-16 BE string.
1504        *
1505        * @return {WordArray} The word array.
1506        *
1507        * @static
1508        *
1509        * @example
1510        *
1511        *     var wordArray = CryptoJS.enc.Utf16.parse(utf16String);
1512        */
1513       parse: function(utf16Str) {
1514         // Shortcut
1515         var utf16StrLength = utf16Str.length;
1516 
1517         // Convert
1518         var words = [];
1519         for (var i = 0; i < utf16StrLength; i++) {
1520           words[i >>> 1] |= utf16Str.charCodeAt(i) << (16 - (i % 2) * 16);
1521         }
1522 
1523         return WordArray.create(words, utf16StrLength * 2);
1524       }
1525     };
1526 
1527     /**
1528      * UTF-16 LE encoding strategy.
1529      */
1530     C_enc.Utf16LE = {
1531       /**
1532        * Converts a word array to a UTF-16 LE string.
1533        *
1534        * @param {WordArray} wordArray The word array.
1535        *
1536        * @return {string} The UTF-16 LE string.
1537        *
1538        * @static
1539        *
1540        * @example
1541        *
1542        *     var utf16Str = CryptoJS.enc.Utf16LE.stringify(wordArray);
1543        */
1544       stringify: function(wordArray) {
1545         // Shortcuts
1546         var words = wordArray.words;
1547         var sigBytes = wordArray.sigBytes;
1548 
1549         // Convert
1550         var utf16Chars = [];
1551         for (var i = 0; i < sigBytes; i += 2) {
1552           var codePoint = swapEndian((words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff);
1553           utf16Chars.push(String.fromCharCode(codePoint));
1554         }
1555 
1556         return utf16Chars.join('');
1557       },
1558 
1559       /**
1560        * Converts a UTF-16 LE string to a word array.
1561        *
1562        * @param {string} utf16Str The UTF-16 LE string.
1563        *
1564        * @return {WordArray} The word array.
1565        *
1566        * @static
1567        *
1568        * @example
1569        *
1570        *     var wordArray = CryptoJS.enc.Utf16LE.parse(utf16Str);
1571        */
1572       parse: function(utf16Str) {
1573         // Shortcut
1574         var utf16StrLength = utf16Str.length;
1575 
1576         // Convert
1577         var words = [];
1578         for (var i = 0; i < utf16StrLength; i++) {
1579           words[i >>> 1] |= swapEndian(utf16Str.charCodeAt(i) << (16 - (i % 2) * 16));
1580         }
1581 
1582         return WordArray.create(words, utf16StrLength * 2);
1583       }
1584     };
1585 
1586     function swapEndian(word) {
1587       return ((word << 8) & 0xff00ff00) | ((word >>> 8) & 0x00ff00ff);
1588     }
1589   }());
1590 
1591 
1592   (function() {
1593     // Check if typed arrays are supported
1594     if (typeof ArrayBuffer != 'function') {
1595       return;
1596     }
1597 
1598     // Shortcuts
1599     var C = CryptoJS;
1600     var C_lib = C.lib;
1601     var WordArray = C_lib.WordArray;
1602 
1603     // Reference original init
1604     var superInit = WordArray.init;
1605 
1606     // Augment WordArray.init to handle typed arrays
1607     var subInit = WordArray.init = function(typedArray) {
1608       // Convert buffers to uint8
1609       if (typedArray instanceof ArrayBuffer) {
1610         typedArray = new Uint8Array(typedArray);
1611       }
1612 
1613       // Convert other array views to uint8
1614       if (
1615         typedArray instanceof Int8Array ||
1616         (typeof Uint8ClampedArray !== "undefined" && typedArray instanceof Uint8ClampedArray) ||
1617         typedArray instanceof Int16Array ||
1618         typedArray instanceof Uint16Array ||
1619         typedArray instanceof Int32Array ||
1620         typedArray instanceof Uint32Array ||
1621         typedArray instanceof Float32Array ||
1622         typedArray instanceof Float64Array
1623       ) {
1624         typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength);
1625       }
1626 
1627       // Handle Uint8Array
1628       if (typedArray instanceof Uint8Array) {
1629         // Shortcut
1630         var typedArrayByteLength = typedArray.byteLength;
1631 
1632         // Extract bytes
1633         var words = [];
1634         for (var i = 0; i < typedArrayByteLength; i++) {
1635           words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8);
1636         }
1637 
1638         // Initialize this word array
1639         superInit.call(this, words, typedArrayByteLength);
1640       } else {
1641         // Else call normal init
1642         superInit.apply(this, arguments);
1643       }
1644     };
1645 
1646     subInit.prototype = WordArray;
1647   }());
1648 
1649 
1650   /** @preserve
1651   (c) 2012 by C��dric Mesnil. All rights reserved.
1652 
1653   Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1654 
1655       - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
1656       - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
1657 
1658   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1659   */
1660 
1661   (function(Math) {
1662     // Shortcuts
1663     var C = CryptoJS;
1664     var C_lib = C.lib;
1665     var WordArray = C_lib.WordArray;
1666     var Hasher = C_lib.Hasher;
1667     var C_algo = C.algo;
1668 
1669     // Constants table
1670     var _zl = WordArray.create([
1671       0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1672       7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
1673       3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
1674       1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
1675       4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
1676     ]);
1677     var _zr = WordArray.create([
1678       5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
1679       6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
1680       15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
1681       8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
1682       12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
1683     ]);
1684     var _sl = WordArray.create([
1685       11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
1686       7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
1687       11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
1688       11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
1689       9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
1690     ]);
1691     var _sr = WordArray.create([
1692       8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
1693       9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
1694       9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
1695       15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
1696       8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
1697     ]);
1698 
1699     var _hl = WordArray.create([0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]);
1700     var _hr = WordArray.create([0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000]);
1701 
1702     /**
1703      * RIPEMD160 hash algorithm.
1704      */
1705     var RIPEMD160 = C_algo.RIPEMD160 = Hasher.extend({
1706       _doReset: function() {
1707         this._hash = WordArray.create([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]);
1708       },
1709 
1710       _doProcessBlock: function(M, offset) {
1711 
1712         // Swap endian
1713         for (var i = 0; i < 16; i++) {
1714           // Shortcuts
1715           var offset_i = offset + i;
1716           var M_offset_i = M[offset_i];
1717 
1718           // Swap
1719           M[offset_i] = (
1720             (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
1721             (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
1722           );
1723         }
1724         // Shortcut
1725         var H = this._hash.words;
1726         var hl = _hl.words;
1727         var hr = _hr.words;
1728         var zl = _zl.words;
1729         var zr = _zr.words;
1730         var sl = _sl.words;
1731         var sr = _sr.words;
1732 
1733         // Working variables
1734         var al, bl, cl, dl, el;
1735         var ar, br, cr, dr, er;
1736 
1737         ar = al = H[0];
1738         br = bl = H[1];
1739         cr = cl = H[2];
1740         dr = dl = H[3];
1741         er = el = H[4];
1742         // Computation
1743         var t;
1744         for (var i = 0; i < 80; i += 1) {
1745           t = (al + M[offset + zl[i]]) | 0;
1746           if (i < 16) {
1747             t += f1(bl, cl, dl) + hl[0];
1748           } else if (i < 32) {
1749             t += f2(bl, cl, dl) + hl[1];
1750           } else if (i < 48) {
1751             t += f3(bl, cl, dl) + hl[2];
1752           } else if (i < 64) {
1753             t += f4(bl, cl, dl) + hl[3];
1754           } else { // if (i<80) {
1755             t += f5(bl, cl, dl) + hl[4];
1756           }
1757           t = t | 0;
1758           t = rotl(t, sl[i]);
1759           t = (t + el) | 0;
1760           al = el;
1761           el = dl;
1762           dl = rotl(cl, 10);
1763           cl = bl;
1764           bl = t;
1765 
1766           t = (ar + M[offset + zr[i]]) | 0;
1767           if (i < 16) {
1768             t += f5(br, cr, dr) + hr[0];
1769           } else if (i < 32) {
1770             t += f4(br, cr, dr) + hr[1];
1771           } else if (i < 48) {
1772             t += f3(br, cr, dr) + hr[2];
1773           } else if (i < 64) {
1774             t += f2(br, cr, dr) + hr[3];
1775           } else { // if (i<80) {
1776             t += f1(br, cr, dr) + hr[4];
1777           }
1778           t = t | 0;
1779           t = rotl(t, sr[i]);
1780           t = (t + er) | 0;
1781           ar = er;
1782           er = dr;
1783           dr = rotl(cr, 10);
1784           cr = br;
1785           br = t;
1786         }
1787         // Intermediate hash value
1788         t = (H[1] + cl + dr) | 0;
1789         H[1] = (H[2] + dl + er) | 0;
1790         H[2] = (H[3] + el + ar) | 0;
1791         H[3] = (H[4] + al + br) | 0;
1792         H[4] = (H[0] + bl + cr) | 0;
1793         H[0] = t;
1794       },
1795 
1796       _doFinalize: function() {
1797         // Shortcuts
1798         var data = this._data;
1799         var dataWords = data.words;
1800 
1801         var nBitsTotal = this._nDataBytes * 8;
1802         var nBitsLeft = data.sigBytes * 8;
1803 
1804         // Add padding
1805         dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
1806         dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
1807           (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) |
1808           (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00)
1809         );
1810         data.sigBytes = (dataWords.length + 1) * 4;
1811 
1812         // Hash final blocks
1813         this._process();
1814 
1815         // Shortcuts
1816         var hash = this._hash;
1817         var H = hash.words;
1818 
1819         // Swap endian
1820         for (var i = 0; i < 5; i++) {
1821           // Shortcut
1822           var H_i = H[i];
1823 
1824           // Swap
1825           H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) |
1826             (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
1827         }
1828 
1829         // Return final computed hash
1830         return hash;
1831       },
1832 
1833       clone: function() {
1834         var clone = Hasher.clone.call(this);
1835         clone._hash = this._hash.clone();
1836 
1837         return clone;
1838       }
1839     });
1840 
1841 
1842     function f1(x, y, z) {
1843       return ((x) ^ (y) ^ (z));
1844 
1845     }
1846 
1847     function f2(x, y, z) {
1848       return (((x) & (y)) | ((~x) & (z)));
1849     }
1850 
1851     function f3(x, y, z) {
1852       return (((x) | (~(y))) ^ (z));
1853     }
1854 
1855     function f4(x, y, z) {
1856       return (((x) & (z)) | ((y) & (~(z))));
1857     }
1858 
1859     function f5(x, y, z) {
1860       return ((x) ^ ((y) | (~(z))));
1861 
1862     }
1863 
1864     function rotl(x, n) {
1865       return (x << n) | (x >>> (32 - n));
1866     }
1867 
1868 
1869     /**
1870      * Shortcut function to the hasher's object interface.
1871      *
1872      * @param {WordArray|string} message The message to hash.
1873      *
1874      * @return {WordArray} The hash.
1875      *
1876      * @static
1877      *
1878      * @example
1879      *
1880      *     var hash = CryptoJS.RIPEMD160('message');
1881      *     var hash = CryptoJS.RIPEMD160(wordArray);
1882      */
1883     C.RIPEMD160 = Hasher._createHelper(RIPEMD160);
1884 
1885     /**
1886      * Shortcut function to the HMAC's object interface.
1887      *
1888      * @param {WordArray|string} message The message to hash.
1889      * @param {WordArray|string} key The secret key.
1890      *
1891      * @return {WordArray} The HMAC.
1892      *
1893      * @static
1894      *
1895      * @example
1896      *
1897      *     var hmac = CryptoJS.HmacRIPEMD160(message, key);
1898      */
1899     C.HmacRIPEMD160 = Hasher._createHmacHelper(RIPEMD160);
1900   }(Math));
1901 
1902 
1903   (function() {
1904     // Shortcuts
1905     var C = CryptoJS;
1906     var C_lib = C.lib;
1907     var Base = C_lib.Base;
1908     var C_enc = C.enc;
1909     var Utf8 = C_enc.Utf8;
1910     var C_algo = C.algo;
1911 
1912     /**
1913      * HMAC algorithm.
1914      */
1915     var HMAC = C_algo.HMAC = Base.extend({
1916       /**
1917        * Initializes a newly created HMAC.
1918        *
1919        * @param {Hasher} hasher The hash algorithm to use.
1920        * @param {WordArray|string} key The secret key.
1921        *
1922        * @example
1923        *
1924        *     var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
1925        */
1926       init: function(hasher, key) {
1927         // Init hasher
1928         hasher = this._hasher = new hasher.init();
1929 
1930         // Convert string to WordArray, else assume WordArray already
1931         if (typeof key == 'string') {
1932           key = Utf8.parse(key);
1933         }
1934 
1935         // Shortcuts
1936         var hasherBlockSize = hasher.blockSize;
1937         var hasherBlockSizeBytes = hasherBlockSize * 4;
1938 
1939         // Allow arbitrary length keys
1940         if (key.sigBytes > hasherBlockSizeBytes) {
1941           key = hasher.finalize(key);
1942         }
1943 
1944         // Clamp excess bits
1945         key.clamp();
1946 
1947         // Clone key for inner and outer pads
1948         var oKey = this._oKey = key.clone();
1949         var iKey = this._iKey = key.clone();
1950 
1951         // Shortcuts
1952         var oKeyWords = oKey.words;
1953         var iKeyWords = iKey.words;
1954 
1955         // XOR keys with pad constants
1956         for (var i = 0; i < hasherBlockSize; i++) {
1957           oKeyWords[i] ^= 0x5c5c5c5c;
1958           iKeyWords[i] ^= 0x36363636;
1959         }
1960         oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes;
1961 
1962         // Set initial values
1963         this.reset();
1964       },
1965 
1966       /**
1967        * Resets this HMAC to its initial state.
1968        *
1969        * @example
1970        *
1971        *     hmacHasher.reset();
1972        */
1973       reset: function() {
1974         // Shortcut
1975         var hasher = this._hasher;
1976 
1977         // Reset
1978         hasher.reset();
1979         hasher.update(this._iKey);
1980       },
1981 
1982       /**
1983        * Updates this HMAC with a message.
1984        *
1985        * @param {WordArray|string} messageUpdate The message to append.
1986        *
1987        * @return {HMAC} This HMAC instance.
1988        *
1989        * @example
1990        *
1991        *     hmacHasher.update('message');
1992        *     hmacHasher.update(wordArray);
1993        */
1994       update: function(messageUpdate) {
1995         this._hasher.update(messageUpdate);
1996 
1997         // Chainable
1998         return this;
1999       },
2000 
2001       /**
2002        * Finalizes the HMAC computation.
2003        * Note that the finalize operation is effectively a destructive, read-once operation.
2004        *
2005        * @param {WordArray|string} messageUpdate (Optional) A final message update.
2006        *
2007        * @return {WordArray} The HMAC.
2008        *
2009        * @example
2010        *
2011        *     var hmac = hmacHasher.finalize();
2012        *     var hmac = hmacHasher.finalize('message');
2013        *     var hmac = hmacHasher.finalize(wordArray);
2014        */
2015       finalize: function(messageUpdate) {
2016         // Shortcut
2017         var hasher = this._hasher;
2018 
2019         // Compute HMAC
2020         var innerHash = hasher.finalize(messageUpdate);
2021         hasher.reset();
2022         var hmac = hasher.finalize(this._oKey.clone().concat(innerHash));
2023 
2024         return hmac;
2025       }
2026     });
2027   }());
2028 
2029 
2030   (function() {
2031     // Shortcuts
2032     var C = CryptoJS;
2033     var C_lib = C.lib;
2034     var Base = C_lib.Base;
2035     var WordArray = C_lib.WordArray;
2036     var C_algo = C.algo;
2037     var SHA1 = C_algo.SHA1;
2038     var HMAC = C_algo.HMAC;
2039 
2040     /**
2041      * Password-Based Key Derivation Function 2 algorithm.
2042      */
2043     var PBKDF2 = C_algo.PBKDF2 = Base.extend({
2044       /**
2045        * Configuration options.
2046        *
2047        * @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
2048        * @property {Hasher} hasher The hasher to use. Default: SHA1
2049        * @property {number} iterations The number of iterations to perform. Default: 1
2050        */
2051       cfg: Base.extend({
2052         keySize: 128 / 32,
2053         hasher: SHA1,
2054         iterations: 1
2055       }),
2056 
2057       /**
2058        * Initializes a newly created key derivation function.
2059        *
2060        * @param {Object} cfg (Optional) The configuration options to use for the derivation.
2061        *
2062        * @example
2063        *
2064        *     var kdf = CryptoJS.algo.PBKDF2.create();
2065        *     var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8 });
2066        *     var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8, iterations: 1000 });
2067        */
2068       init: function(cfg) {
2069         this.cfg = this.cfg.extend(cfg);
2070       },
2071 
2072       /**
2073        * Computes the Password-Based Key Derivation Function 2.
2074        *
2075        * @param {WordArray|string} password The password.
2076        * @param {WordArray|string} salt A salt.
2077        *
2078        * @return {WordArray} The derived key.
2079        *
2080        * @example
2081        *
2082        *     var key = kdf.compute(password, salt);
2083        */
2084       compute: function(password, salt) {
2085         // Shortcut
2086         var cfg = this.cfg;
2087 
2088         // Init HMAC
2089         var hmac = HMAC.create(cfg.hasher, password);
2090 
2091         // Initial values
2092         var derivedKey = WordArray.create();
2093         var blockIndex = WordArray.create([0x00000001]);
2094 
2095         // Shortcuts
2096         var derivedKeyWords = derivedKey.words;
2097         var blockIndexWords = blockIndex.words;
2098         var keySize = cfg.keySize;
2099         var iterations = cfg.iterations;
2100 
2101         // Generate key
2102         while (derivedKeyWords.length < keySize) {
2103           var block = hmac.update(salt).finalize(blockIndex);
2104           hmac.reset();
2105 
2106           // Shortcuts
2107           var blockWords = block.words;
2108           var blockWordsLength = blockWords.length;
2109 
2110           // Iterations
2111           var intermediate = block;
2112           for (var i = 1; i < iterations; i++) {
2113             intermediate = hmac.finalize(intermediate);
2114             hmac.reset();
2115 
2116             // Shortcut
2117             var intermediateWords = intermediate.words;
2118 
2119             // XOR intermediate with block
2120             for (var j = 0; j < blockWordsLength; j++) {
2121               blockWords[j] ^= intermediateWords[j];
2122             }
2123           }
2124 
2125           derivedKey.concat(block);
2126           blockIndexWords[0]++;
2127         }
2128         derivedKey.sigBytes = keySize * 4;
2129 
2130         return derivedKey;
2131       }
2132     });
2133 
2134     /**
2135      * Computes the Password-Based Key Derivation Function 2.
2136      *
2137      * @param {WordArray|string} password The password.
2138      * @param {WordArray|string} salt A salt.
2139      * @param {Object} cfg (Optional) The configuration options to use for this computation.
2140      *
2141      * @return {WordArray} The derived key.
2142      *
2143      * @static
2144      *
2145      * @example
2146      *
2147      *     var key = CryptoJS.PBKDF2(password, salt);
2148      *     var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 });
2149      *     var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 });
2150      */
2151     C.PBKDF2 = function(password, salt, cfg) {
2152       return PBKDF2.create(cfg).compute(password, salt);
2153     };
2154   }());
2155 
2156 
2157   (function() {
2158     // Shortcuts
2159     var C = CryptoJS;
2160     var C_lib = C.lib;
2161     var Base = C_lib.Base;
2162     var WordArray = C_lib.WordArray;
2163     var C_algo = C.algo;
2164     var MD5 = C_algo.MD5;
2165 
2166     /**
2167      * This key derivation function is meant to conform with EVP_BytesToKey.
2168      * www.openssl.org/docs/crypto/EVP_BytesToKey.html
2169      */
2170     var EvpKDF = C_algo.EvpKDF = Base.extend({
2171       /**
2172        * Configuration options.
2173        *
2174        * @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
2175        * @property {Hasher} hasher The hash algorithm to use. Default: MD5
2176        * @property {number} iterations The number of iterations to perform. Default: 1
2177        */
2178       cfg: Base.extend({
2179         keySize: 128 / 32,
2180         hasher: MD5,
2181         iterations: 1
2182       }),
2183 
2184       /**
2185        * Initializes a newly created key derivation function.
2186        *
2187        * @param {Object} cfg (Optional) The configuration options to use for the derivation.
2188        *
2189        * @example
2190        *
2191        *     var kdf = CryptoJS.algo.EvpKDF.create();
2192        *     var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 });
2193        *     var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 });
2194        */
2195       init: function(cfg) {
2196         this.cfg = this.cfg.extend(cfg);
2197       },
2198 
2199       /**
2200        * Derives a key from a password.
2201        *
2202        * @param {WordArray|string} password The password.
2203        * @param {WordArray|string} salt A salt.
2204        *
2205        * @return {WordArray} The derived key.
2206        *
2207        * @example
2208        *
2209        *     var key = kdf.compute(password, salt);
2210        */
2211       compute: function(password, salt) {
2212         var block;
2213 
2214         // Shortcut
2215         var cfg = this.cfg;
2216 
2217         // Init hasher
2218         var hasher = cfg.hasher.create();
2219 
2220         // Initial values
2221         var derivedKey = WordArray.create();
2222 
2223         // Shortcuts
2224         var derivedKeyWords = derivedKey.words;
2225         var keySize = cfg.keySize;
2226         var iterations = cfg.iterations;
2227 
2228         // Generate key
2229         while (derivedKeyWords.length < keySize) {
2230           if (block) {
2231             hasher.update(block);
2232           }
2233           block = hasher.update(password).finalize(salt);
2234           hasher.reset();
2235 
2236           // Iterations
2237           for (var i = 1; i < iterations; i++) {
2238             block = hasher.finalize(block);
2239             hasher.reset();
2240           }
2241 
2242           derivedKey.concat(block);
2243         }
2244         derivedKey.sigBytes = keySize * 4;
2245 
2246         return derivedKey;
2247       }
2248     });
2249 
2250     /**
2251      * Derives a key from a password.
2252      *
2253      * @param {WordArray|string} password The password.
2254      * @param {WordArray|string} salt A salt.
2255      * @param {Object} cfg (Optional) The configuration options to use for this computation.
2256      *
2257      * @return {WordArray} The derived key.
2258      *
2259      * @static
2260      *
2261      * @example
2262      *
2263      *     var key = CryptoJS.EvpKDF(password, salt);
2264      *     var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 });
2265      *     var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 });
2266      */
2267     C.EvpKDF = function(password, salt, cfg) {
2268       return EvpKDF.create(cfg).compute(password, salt);
2269     };
2270   }());
2271 
2272 
2273   (function() {
2274     // Shortcuts
2275     var C = CryptoJS;
2276     var C_lib = C.lib;
2277     var WordArray = C_lib.WordArray;
2278     var C_algo = C.algo;
2279     var SHA256 = C_algo.SHA256;
2280 
2281     /**
2282      * SHA-224 hash algorithm.
2283      */
2284     var SHA224 = C_algo.SHA224 = SHA256.extend({
2285       _doReset: function() {
2286         this._hash = new WordArray.init([
2287           0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
2288           0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
2289         ]);
2290       },
2291 
2292       _doFinalize: function() {
2293         var hash = SHA256._doFinalize.call(this);
2294 
2295         hash.sigBytes -= 4;
2296 
2297         return hash;
2298       }
2299     });
2300 
2301     /**
2302      * Shortcut function to the hasher's object interface.
2303      *
2304      * @param {WordArray|string} message The message to hash.
2305      *
2306      * @return {WordArray} The hash.
2307      *
2308      * @static
2309      *
2310      * @example
2311      *
2312      *     var hash = CryptoJS.SHA224('message');
2313      *     var hash = CryptoJS.SHA224(wordArray);
2314      */
2315     C.SHA224 = SHA256._createHelper(SHA224);
2316 
2317     /**
2318      * Shortcut function to the HMAC's object interface.
2319      *
2320      * @param {WordArray|string} message The message to hash.
2321      * @param {WordArray|string} key The secret key.
2322      *
2323      * @return {WordArray} The HMAC.
2324      *
2325      * @static
2326      *
2327      * @example
2328      *
2329      *     var hmac = CryptoJS.HmacSHA224(message, key);
2330      */
2331     C.HmacSHA224 = SHA256._createHmacHelper(SHA224);
2332   }());
2333 
2334 
2335   (function(undefined) {
2336     // Shortcuts
2337     var C = CryptoJS;
2338     var C_lib = C.lib;
2339     var Base = C_lib.Base;
2340     var X32WordArray = C_lib.WordArray;
2341 
2342     /**
2343      * x64 namespace.
2344      */
2345     var C_x64 = C.x64 = {};
2346 
2347     /**
2348      * A 64-bit word.
2349      */
2350     var X64Word = C_x64.Word = Base.extend({
2351       /**
2352        * Initializes a newly created 64-bit word.
2353        *
2354        * @param {number} high The high 32 bits.
2355        * @param {number} low The low 32 bits.
2356        *
2357        * @example
2358        *
2359        *     var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607);
2360        */
2361       init: function(high, low) {
2362         this.high = high;
2363         this.low = low;
2364       }
2365 
2366       /**
2367        * Bitwise NOTs this word.
2368        *
2369        * @return {X64Word} A new x64-Word object after negating.
2370        *
2371        * @example
2372        *
2373        *     var negated = x64Word.not();
2374        */
2375       // not: function () {
2376       // var high = ~this.high;
2377       // var low = ~this.low;
2378 
2379       // return X64Word.create(high, low);
2380       // },
2381 
2382       /**
2383        * Bitwise ANDs this word with the passed word.
2384        *
2385        * @param {X64Word} word The x64-Word to AND with this word.
2386        *
2387        * @return {X64Word} A new x64-Word object after ANDing.
2388        *
2389        * @example
2390        *
2391        *     var anded = x64Word.and(anotherX64Word);
2392        */
2393       // and: function (word) {
2394       // var high = this.high & word.high;
2395       // var low = this.low & word.low;
2396 
2397       // return X64Word.create(high, low);
2398       // },
2399 
2400       /**
2401        * Bitwise ORs this word with the passed word.
2402        *
2403        * @param {X64Word} word The x64-Word to OR with this word.
2404        *
2405        * @return {X64Word} A new x64-Word object after ORing.
2406        *
2407        * @example
2408        *
2409        *     var ored = x64Word.or(anotherX64Word);
2410        */
2411       // or: function (word) {
2412       // var high = this.high | word.high;
2413       // var low = this.low | word.low;
2414 
2415       // return X64Word.create(high, low);
2416       // },
2417 
2418       /**
2419        * Bitwise XORs this word with the passed word.
2420        *
2421        * @param {X64Word} word The x64-Word to XOR with this word.
2422        *
2423        * @return {X64Word} A new x64-Word object after XORing.
2424        *
2425        * @example
2426        *
2427        *     var xored = x64Word.xor(anotherX64Word);
2428        */
2429       // xor: function (word) {
2430       // var high = this.high ^ word.high;
2431       // var low = this.low ^ word.low;
2432 
2433       // return X64Word.create(high, low);
2434       // },
2435 
2436       /**
2437        * Shifts this word n bits to the left.
2438        *
2439        * @param {number} n The number of bits to shift.
2440        *
2441        * @return {X64Word} A new x64-Word object after shifting.
2442        *
2443        * @example
2444        *
2445        *     var shifted = x64Word.shiftL(25);
2446        */
2447       // shiftL: function (n) {
2448       // if (n < 32) {
2449       // var high = (this.high << n) | (this.low >>> (32 - n));
2450       // var low = this.low << n;
2451       // } else {
2452       // var high = this.low << (n - 32);
2453       // var low = 0;
2454       // }
2455 
2456       // return X64Word.create(high, low);
2457       // },
2458 
2459       /**
2460        * Shifts this word n bits to the right.
2461        *
2462        * @param {number} n The number of bits to shift.
2463        *
2464        * @return {X64Word} A new x64-Word object after shifting.
2465        *
2466        * @example
2467        *
2468        *     var shifted = x64Word.shiftR(7);
2469        */
2470       // shiftR: function (n) {
2471       // if (n < 32) {
2472       // var low = (this.low >>> n) | (this.high << (32 - n));
2473       // var high = this.high >>> n;
2474       // } else {
2475       // var low = this.high >>> (n - 32);
2476       // var high = 0;
2477       // }
2478 
2479       // return X64Word.create(high, low);
2480       // },
2481 
2482       /**
2483        * Rotates this word n bits to the left.
2484        *
2485        * @param {number} n The number of bits to rotate.
2486        *
2487        * @return {X64Word} A new x64-Word object after rotating.
2488        *
2489        * @example
2490        *
2491        *     var rotated = x64Word.rotL(25);
2492        */
2493       // rotL: function (n) {
2494       // return this.shiftL(n).or(this.shiftR(64 - n));
2495       // },
2496 
2497       /**
2498        * Rotates this word n bits to the right.
2499        *
2500        * @param {number} n The number of bits to rotate.
2501        *
2502        * @return {X64Word} A new x64-Word object after rotating.
2503        *
2504        * @example
2505        *
2506        *     var rotated = x64Word.rotR(7);
2507        */
2508       // rotR: function (n) {
2509       // return this.shiftR(n).or(this.shiftL(64 - n));
2510       // },
2511 
2512       /**
2513        * Adds this word with the passed word.
2514        *
2515        * @param {X64Word} word The x64-Word to add with this word.
2516        *
2517        * @return {X64Word} A new x64-Word object after adding.
2518        *
2519        * @example
2520        *
2521        *     var added = x64Word.add(anotherX64Word);
2522        */
2523       // add: function (word) {
2524       // var low = (this.low + word.low) | 0;
2525       // var carry = (low >>> 0) < (this.low >>> 0) ? 1 : 0;
2526       // var high = (this.high + word.high + carry) | 0;
2527 
2528       // return X64Word.create(high, low);
2529       // }
2530     });
2531 
2532     /**
2533      * An array of 64-bit words.
2534      *
2535      * @property {Array} words The array of CryptoJS.x64.Word objects.
2536      * @property {number} sigBytes The number of significant bytes in this word array.
2537      */
2538     var X64WordArray = C_x64.WordArray = Base.extend({
2539       /**
2540        * Initializes a newly created word array.
2541        *
2542        * @param {Array} words (Optional) An array of CryptoJS.x64.Word objects.
2543        * @param {number} sigBytes (Optional) The number of significant bytes in the words.
2544        *
2545        * @example
2546        *
2547        *     var wordArray = CryptoJS.x64.WordArray.create();
2548        *
2549        *     var wordArray = CryptoJS.x64.WordArray.create([
2550        *         CryptoJS.x64.Word.create(0x00010203, 0x04050607),
2551        *         CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)
2552        *     ]);
2553        *
2554        *     var wordArray = CryptoJS.x64.WordArray.create([
2555        *         CryptoJS.x64.Word.create(0x00010203, 0x04050607),
2556        *         CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)
2557        *     ], 10);
2558        */
2559       init: function(words, sigBytes) {
2560         words = this.words = words || [];
2561 
2562         if (sigBytes != undefined) {
2563           this.sigBytes = sigBytes;
2564         } else {
2565           this.sigBytes = words.length * 8;
2566         }
2567       },
2568 
2569       /**
2570        * Converts this 64-bit word array to a 32-bit word array.
2571        *
2572        * @return {CryptoJS.lib.WordArray} This word array's data as a 32-bit word array.
2573        *
2574        * @example
2575        *
2576        *     var x32WordArray = x64WordArray.toX32();
2577        */
2578       toX32: function() {
2579         // Shortcuts
2580         var x64Words = this.words;
2581         var x64WordsLength = x64Words.length;
2582 
2583         // Convert
2584         var x32Words = [];
2585         for (var i = 0; i < x64WordsLength; i++) {
2586           var x64Word = x64Words[i];
2587           x32Words.push(x64Word.high);
2588           x32Words.push(x64Word.low);
2589         }
2590 
2591         return X32WordArray.create(x32Words, this.sigBytes);
2592       },
2593 
2594       /**
2595        * Creates a copy of this word array.
2596        *
2597        * @return {X64WordArray} The clone.
2598        *
2599        * @example
2600        *
2601        *     var clone = x64WordArray.clone();
2602        */
2603       clone: function() {
2604         var clone = Base.clone.call(this);
2605 
2606         // Clone "words" array
2607         var words = clone.words = this.words.slice(0);
2608 
2609         // Clone each X64Word object
2610         var wordsLength = words.length;
2611         for (var i = 0; i < wordsLength; i++) {
2612           words[i] = words[i].clone();
2613         }
2614 
2615         return clone;
2616       }
2617     });
2618   }());
2619 
2620 
2621   (function(Math) {
2622     // Shortcuts
2623     var C = CryptoJS;
2624     var C_lib = C.lib;
2625     var WordArray = C_lib.WordArray;
2626     var Hasher = C_lib.Hasher;
2627     var C_x64 = C.x64;
2628     var X64Word = C_x64.Word;
2629     var C_algo = C.algo;
2630 
2631     // Constants tables
2632     var RHO_OFFSETS = [];
2633     var PI_INDEXES = [];
2634     var ROUND_CONSTANTS = [];
2635 
2636     // Compute Constants
2637     (function() {
2638       // Compute rho offset constants
2639       var x = 1,
2640         y = 0;
2641       for (var t = 0; t < 24; t++) {
2642         RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64;
2643 
2644         var newX = y % 5;
2645         var newY = (2 * x + 3 * y) % 5;
2646         x = newX;
2647         y = newY;
2648       }
2649 
2650       // Compute pi index constants
2651       for (var x = 0; x < 5; x++) {
2652         for (var y = 0; y < 5; y++) {
2653           PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5;
2654         }
2655       }
2656 
2657       // Compute round constants
2658       var LFSR = 0x01;
2659       for (var i = 0; i < 24; i++) {
2660         var roundConstantMsw = 0;
2661         var roundConstantLsw = 0;
2662 
2663         for (var j = 0; j < 7; j++) {
2664           if (LFSR & 0x01) {
2665             var bitPosition = (1 << j) - 1;
2666             if (bitPosition < 32) {
2667               roundConstantLsw ^= 1 << bitPosition;
2668             } else /* if (bitPosition >= 32) */ {
2669               roundConstantMsw ^= 1 << (bitPosition - 32);
2670             }
2671           }
2672 
2673           // Compute next LFSR
2674           if (LFSR & 0x80) {
2675             // Primitive polynomial over GF(2): x^8 + x^6 + x^5 + x^4 + 1
2676             LFSR = (LFSR << 1) ^ 0x71;
2677           } else {
2678             LFSR <<= 1;
2679           }
2680         }
2681 
2682         ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw);
2683       }
2684     }());
2685 
2686     // Reusable objects for temporary values
2687     var T = [];
2688     (function() {
2689       for (var i = 0; i < 25; i++) {
2690         T[i] = X64Word.create();
2691       }
2692     }());
2693 
2694     /**
2695      * SHA-3 hash algorithm.
2696      */
2697     var SHA3 = C_algo.SHA3 = Hasher.extend({
2698       /**
2699        * Configuration options.
2700        *
2701        * @property {number} outputLength
2702        *   The desired number of bits in the output hash.
2703        *   Only values permitted are: 224, 256, 384, 512.
2704        *   Default: 512
2705        */
2706       cfg: Hasher.cfg.extend({
2707         outputLength: 512
2708       }),
2709 
2710       _doReset: function() {
2711         var state = this._state = []
2712         for (var i = 0; i < 25; i++) {
2713           state[i] = new X64Word.init();
2714         }
2715 
2716         this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32;
2717       },
2718 
2719       _doProcessBlock: function(M, offset) {
2720         // Shortcuts
2721         var state = this._state;
2722         var nBlockSizeLanes = this.blockSize / 2;
2723 
2724         // Absorb
2725         for (var i = 0; i < nBlockSizeLanes; i++) {
2726           // Shortcuts
2727           var M2i = M[offset + 2 * i];
2728           var M2i1 = M[offset + 2 * i + 1];
2729 
2730           // Swap endian
2731           M2i = (
2732             (((M2i << 8) | (M2i >>> 24)) & 0x00ff00ff) |
2733             (((M2i << 24) | (M2i >>> 8)) & 0xff00ff00)
2734           );
2735           M2i1 = (
2736             (((M2i1 << 8) | (M2i1 >>> 24)) & 0x00ff00ff) |
2737             (((M2i1 << 24) | (M2i1 >>> 8)) & 0xff00ff00)
2738           );
2739 
2740           // Absorb message into state
2741           var lane = state[i];
2742           lane.high ^= M2i1;
2743           lane.low ^= M2i;
2744         }
2745 
2746         // Rounds
2747         for (var round = 0; round < 24; round++) {
2748           // Theta
2749           for (var x = 0; x < 5; x++) {
2750             // Mix column lanes
2751             var tMsw = 0,
2752               tLsw = 0;
2753             for (var y = 0; y < 5; y++) {
2754               var lane = state[x + 5 * y];
2755               tMsw ^= lane.high;
2756               tLsw ^= lane.low;
2757             }
2758 
2759             // Temporary values
2760             var Tx = T[x];
2761             Tx.high = tMsw;
2762             Tx.low = tLsw;
2763           }
2764           for (var x = 0; x < 5; x++) {
2765             // Shortcuts
2766             var Tx4 = T[(x + 4) % 5];
2767             var Tx1 = T[(x + 1) % 5];
2768             var Tx1Msw = Tx1.high;
2769             var Tx1Lsw = Tx1.low;
2770 
2771             // Mix surrounding columns
2772             var tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31));
2773             var tLsw = Tx4.low ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31));
2774             for (var y = 0; y < 5; y++) {
2775               var lane = state[x + 5 * y];
2776               lane.high ^= tMsw;
2777               lane.low ^= tLsw;
2778             }
2779           }
2780 
2781           // Rho Pi
2782           for (var laneIndex = 1; laneIndex < 25; laneIndex++) {
2783             var tMsw;
2784             var tLsw;
2785 
2786             // Shortcuts
2787             var lane = state[laneIndex];
2788             var laneMsw = lane.high;
2789             var laneLsw = lane.low;
2790             var rhoOffset = RHO_OFFSETS[laneIndex];
2791 
2792             // Rotate lanes
2793             if (rhoOffset < 32) {
2794               tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset));
2795               tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset));
2796             } else /* if (rhoOffset >= 32) */ {
2797               tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset));
2798               tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset));
2799             }
2800 
2801             // Transpose lanes
2802             var TPiLane = T[PI_INDEXES[laneIndex]];
2803             TPiLane.high = tMsw;
2804             TPiLane.low = tLsw;
2805           }
2806 
2807           // Rho pi at x = y = 0
2808           var T0 = T[0];
2809           var state0 = state[0];
2810           T0.high = state0.high;
2811           T0.low = state0.low;
2812 
2813           // Chi
2814           for (var x = 0; x < 5; x++) {
2815             for (var y = 0; y < 5; y++) {
2816               // Shortcuts
2817               var laneIndex = x + 5 * y;
2818               var lane = state[laneIndex];
2819               var TLane = T[laneIndex];
2820               var Tx1Lane = T[((x + 1) % 5) + 5 * y];
2821               var Tx2Lane = T[((x + 2) % 5) + 5 * y];
2822 
2823               // Mix rows
2824               lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high);
2825               lane.low = TLane.low ^ (~Tx1Lane.low & Tx2Lane.low);
2826             }
2827           }
2828 
2829           // Iota
2830           var lane = state[0];
2831           var roundConstant = ROUND_CONSTANTS[round];
2832           lane.high ^= roundConstant.high;
2833           lane.low ^= roundConstant.low;
2834         }
2835       },
2836 
2837       _doFinalize: function() {
2838         // Shortcuts
2839         var data = this._data;
2840         var dataWords = data.words;
2841         var nBitsTotal = this._nDataBytes * 8;
2842         var nBitsLeft = data.sigBytes * 8;
2843         var blockSizeBits = this.blockSize * 32;
2844 
2845         // Add padding
2846         dataWords[nBitsLeft >>> 5] |= 0x1 << (24 - nBitsLeft % 32);
2847         dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80;
2848         data.sigBytes = dataWords.length * 4;
2849 
2850         // Hash final blocks
2851         this._process();
2852 
2853         // Shortcuts
2854         var state = this._state;
2855         var outputLengthBytes = this.cfg.outputLength / 8;
2856         var outputLengthLanes = outputLengthBytes / 8;
2857 
2858         // Squeeze
2859         var hashWords = [];
2860         for (var i = 0; i < outputLengthLanes; i++) {
2861           // Shortcuts
2862           var lane = state[i];
2863           var laneMsw = lane.high;
2864           var laneLsw = lane.low;
2865 
2866           // Swap endian
2867           laneMsw = (
2868             (((laneMsw << 8) | (laneMsw >>> 24)) & 0x00ff00ff) |
2869             (((laneMsw << 24) | (laneMsw >>> 8)) & 0xff00ff00)
2870           );
2871           laneLsw = (
2872             (((laneLsw << 8) | (laneLsw >>> 24)) & 0x00ff00ff) |
2873             (((laneLsw << 24) | (laneLsw >>> 8)) & 0xff00ff00)
2874           );
2875 
2876           // Squeeze state to retrieve hash
2877           hashWords.push(laneLsw);
2878           hashWords.push(laneMsw);
2879         }
2880 
2881         // Return final computed hash
2882         return new WordArray.init(hashWords, outputLengthBytes);
2883       },
2884 
2885       clone: function() {
2886         var clone = Hasher.clone.call(this);
2887 
2888         var state = clone._state = this._state.slice(0);
2889         for (var i = 0; i < 25; i++) {
2890           state[i] = state[i].clone();
2891         }
2892 
2893         return clone;
2894       }
2895     });
2896 
2897     /**
2898      * Shortcut function to the hasher's object interface.
2899      *
2900      * @param {WordArray|string} message The message to hash.
2901      *
2902      * @return {WordArray} The hash.
2903      *
2904      * @static
2905      *
2906      * @example
2907      *
2908      *     var hash = CryptoJS.SHA3('message');
2909      *     var hash = CryptoJS.SHA3(wordArray);
2910      */
2911     C.SHA3 = Hasher._createHelper(SHA3);
2912 
2913     /**
2914      * Shortcut function to the HMAC's object interface.
2915      *
2916      * @param {WordArray|string} message The message to hash.
2917      * @param {WordArray|string} key The secret key.
2918      *
2919      * @return {WordArray} The HMAC.
2920      *
2921      * @static
2922      *
2923      * @example
2924      *
2925      *     var hmac = CryptoJS.HmacSHA3(message, key);
2926      */
2927     C.HmacSHA3 = Hasher._createHmacHelper(SHA3);
2928   }(Math));
2929 
2930 
2931   (function() {
2932     // Shortcuts
2933     var C = CryptoJS;
2934     var C_lib = C.lib;
2935     var Hasher = C_lib.Hasher;
2936     var C_x64 = C.x64;
2937     var X64Word = C_x64.Word;
2938     var X64WordArray = C_x64.WordArray;
2939     var C_algo = C.algo;
2940 
2941     function X64Word_create() {
2942       return X64Word.create.apply(X64Word, arguments);
2943     }
2944 
2945     // Constants
2946     var K = [
2947       X64Word_create(0x428a2f98, 0xd728ae22), X64Word_create(0x71374491, 0x23ef65cd),
2948       X64Word_create(0xb5c0fbcf, 0xec4d3b2f), X64Word_create(0xe9b5dba5, 0x8189dbbc),
2949       X64Word_create(0x3956c25b, 0xf348b538), X64Word_create(0x59f111f1, 0xb605d019),
2950       X64Word_create(0x923f82a4, 0xaf194f9b), X64Word_create(0xab1c5ed5, 0xda6d8118),
2951       X64Word_create(0xd807aa98, 0xa3030242), X64Word_create(0x12835b01, 0x45706fbe),
2952       X64Word_create(0x243185be, 0x4ee4b28c), X64Word_create(0x550c7dc3, 0xd5ffb4e2),
2953       X64Word_create(0x72be5d74, 0xf27b896f), X64Word_create(0x80deb1fe, 0x3b1696b1),
2954       X64Word_create(0x9bdc06a7, 0x25c71235), X64Word_create(0xc19bf174, 0xcf692694),
2955       X64Word_create(0xe49b69c1, 0x9ef14ad2), X64Word_create(0xefbe4786, 0x384f25e3),
2956       X64Word_create(0x0fc19dc6, 0x8b8cd5b5), X64Word_create(0x240ca1cc, 0x77ac9c65),
2957       X64Word_create(0x2de92c6f, 0x592b0275), X64Word_create(0x4a7484aa, 0x6ea6e483),
2958       X64Word_create(0x5cb0a9dc, 0xbd41fbd4), X64Word_create(0x76f988da, 0x831153b5),
2959       X64Word_create(0x983e5152, 0xee66dfab), X64Word_create(0xa831c66d, 0x2db43210),
2960       X64Word_create(0xb00327c8, 0x98fb213f), X64Word_create(0xbf597fc7, 0xbeef0ee4),
2961       X64Word_create(0xc6e00bf3, 0x3da88fc2), X64Word_create(0xd5a79147, 0x930aa725),
2962       X64Word_create(0x06ca6351, 0xe003826f), X64Word_create(0x14292967, 0x0a0e6e70),
2963       X64Word_create(0x27b70a85, 0x46d22ffc), X64Word_create(0x2e1b2138, 0x5c26c926),
2964       X64Word_create(0x4d2c6dfc, 0x5ac42aed), X64Word_create(0x53380d13, 0x9d95b3df),
2965       X64Word_create(0x650a7354, 0x8baf63de), X64Word_create(0x766a0abb, 0x3c77b2a8),
2966       X64Word_create(0x81c2c92e, 0x47edaee6), X64Word_create(0x92722c85, 0x1482353b),
2967       X64Word_create(0xa2bfe8a1, 0x4cf10364), X64Word_create(0xa81a664b, 0xbc423001),
2968       X64Word_create(0xc24b8b70, 0xd0f89791), X64Word_create(0xc76c51a3, 0x0654be30),
2969       X64Word_create(0xd192e819, 0xd6ef5218), X64Word_create(0xd6990624, 0x5565a910),
2970       X64Word_create(0xf40e3585, 0x5771202a), X64Word_create(0x106aa070, 0x32bbd1b8),
2971       X64Word_create(0x19a4c116, 0xb8d2d0c8), X64Word_create(0x1e376c08, 0x5141ab53),
2972       X64Word_create(0x2748774c, 0xdf8eeb99), X64Word_create(0x34b0bcb5, 0xe19b48a8),
2973       X64Word_create(0x391c0cb3, 0xc5c95a63), X64Word_create(0x4ed8aa4a, 0xe3418acb),
2974       X64Word_create(0x5b9cca4f, 0x7763e373), X64Word_create(0x682e6ff3, 0xd6b2b8a3),
2975       X64Word_create(0x748f82ee, 0x5defb2fc), X64Word_create(0x78a5636f, 0x43172f60),
2976       X64Word_create(0x84c87814, 0xa1f0ab72), X64Word_create(0x8cc70208, 0x1a6439ec),
2977       X64Word_create(0x90befffa, 0x23631e28), X64Word_create(0xa4506ceb, 0xde82bde9),
2978       X64Word_create(0xbef9a3f7, 0xb2c67915), X64Word_create(0xc67178f2, 0xe372532b),
2979       X64Word_create(0xca273ece, 0xea26619c), X64Word_create(0xd186b8c7, 0x21c0c207),
2980       X64Word_create(0xeada7dd6, 0xcde0eb1e), X64Word_create(0xf57d4f7f, 0xee6ed178),
2981       X64Word_create(0x06f067aa, 0x72176fba), X64Word_create(0x0a637dc5, 0xa2c898a6),
2982       X64Word_create(0x113f9804, 0xbef90dae), X64Word_create(0x1b710b35, 0x131c471b),
2983       X64Word_create(0x28db77f5, 0x23047d84), X64Word_create(0x32caab7b, 0x40c72493),
2984       X64Word_create(0x3c9ebe0a, 0x15c9bebc), X64Word_create(0x431d67c4, 0x9c100d4c),
2985       X64Word_create(0x4cc5d4be, 0xcb3e42b6), X64Word_create(0x597f299c, 0xfc657e2a),
2986       X64Word_create(0x5fcb6fab, 0x3ad6faec), X64Word_create(0x6c44198c, 0x4a475817)
2987     ];
2988 
2989     // Reusable objects
2990     var W = [];
2991     (function() {
2992       for (var i = 0; i < 80; i++) {
2993         W[i] = X64Word_create();
2994       }
2995     }());
2996 
2997     /**
2998      * SHA-512 hash algorithm.
2999      */
3000     var SHA512 = C_algo.SHA512 = Hasher.extend({
3001       _doReset: function() {
3002         this._hash = new X64WordArray.init([
3003           new X64Word.init(0x6a09e667, 0xf3bcc908), new X64Word.init(0xbb67ae85, 0x84caa73b),
3004           new X64Word.init(0x3c6ef372, 0xfe94f82b), new X64Word.init(0xa54ff53a, 0x5f1d36f1),
3005           new X64Word.init(0x510e527f, 0xade682d1), new X64Word.init(0x9b05688c, 0x2b3e6c1f),
3006           new X64Word.init(0x1f83d9ab, 0xfb41bd6b), new X64Word.init(0x5be0cd19, 0x137e2179)
3007         ]);
3008       },
3009 
3010       _doProcessBlock: function(M, offset) {
3011         // Shortcuts
3012         var H = this._hash.words;
3013 
3014         var H0 = H[0];
3015         var H1 = H[1];
3016         var H2 = H[2];
3017         var H3 = H[3];
3018         var H4 = H[4];
3019         var H5 = H[5];
3020         var H6 = H[6];
3021         var H7 = H[7];
3022 
3023         var H0h = H0.high;
3024         var H0l = H0.low;
3025         var H1h = H1.high;
3026         var H1l = H1.low;
3027         var H2h = H2.high;
3028         var H2l = H2.low;
3029         var H3h = H3.high;
3030         var H3l = H3.low;
3031         var H4h = H4.high;
3032         var H4l = H4.low;
3033         var H5h = H5.high;
3034         var H5l = H5.low;
3035         var H6h = H6.high;
3036         var H6l = H6.low;
3037         var H7h = H7.high;
3038         var H7l = H7.low;
3039 
3040         // Working variables
3041         var ah = H0h;
3042         var al = H0l;
3043         var bh = H1h;
3044         var bl = H1l;
3045         var ch = H2h;
3046         var cl = H2l;
3047         var dh = H3h;
3048         var dl = H3l;
3049         var eh = H4h;
3050         var el = H4l;
3051         var fh = H5h;
3052         var fl = H5l;
3053         var gh = H6h;
3054         var gl = H6l;
3055         var hh = H7h;
3056         var hl = H7l;
3057 
3058         // Rounds
3059         for (var i = 0; i < 80; i++) {
3060           var Wil;
3061           var Wih;
3062 
3063           // Shortcut
3064           var Wi = W[i];
3065 
3066           // Extend message
3067           if (i < 16) {
3068             Wih = Wi.high = M[offset + i * 2] | 0;
3069             Wil = Wi.low = M[offset + i * 2 + 1] | 0;
3070           } else {
3071             // Gamma0
3072             var gamma0x = W[i - 15];
3073             var gamma0xh = gamma0x.high;
3074             var gamma0xl = gamma0x.low;
3075             var gamma0h = ((gamma0xh >>> 1) | (gamma0xl << 31)) ^ ((gamma0xh >>> 8) | (gamma0xl << 24)) ^ (gamma0xh >>> 7);
3076             var gamma0l = ((gamma0xl >>> 1) | (gamma0xh << 31)) ^ ((gamma0xl >>> 8) | (gamma0xh << 24)) ^ ((gamma0xl >>> 7) | (gamma0xh << 25));
3077 
3078             // Gamma1
3079             var gamma1x = W[i - 2];
3080             var gamma1xh = gamma1x.high;
3081             var gamma1xl = gamma1x.low;
3082             var gamma1h = ((gamma1xh >>> 19) | (gamma1xl << 13)) ^ ((gamma1xh << 3) | (gamma1xl >>> 29)) ^ (gamma1xh >>> 6);
3083             var gamma1l = ((gamma1xl >>> 19) | (gamma1xh << 13)) ^ ((gamma1xl << 3) | (gamma1xh >>> 29)) ^ ((gamma1xl >>> 6) | (gamma1xh << 26));
3084 
3085             // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]
3086             var Wi7 = W[i - 7];
3087             var Wi7h = Wi7.high;
3088             var Wi7l = Wi7.low;
3089 
3090             var Wi16 = W[i - 16];
3091             var Wi16h = Wi16.high;
3092             var Wi16l = Wi16.low;
3093 
3094             Wil = gamma0l + Wi7l;
3095             Wih = gamma0h + Wi7h + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0);
3096             Wil = Wil + gamma1l;
3097             Wih = Wih + gamma1h + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0);
3098             Wil = Wil + Wi16l;
3099             Wih = Wih + Wi16h + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0);
3100 
3101             Wi.high = Wih;
3102             Wi.low = Wil;
3103           }
3104 
3105           var chh = (eh & fh) ^ (~eh & gh);
3106           var chl = (el & fl) ^ (~el & gl);
3107           var majh = (ah & bh) ^ (ah & ch) ^ (bh & ch);
3108           var majl = (al & bl) ^ (al & cl) ^ (bl & cl);
3109 
3110           var sigma0h = ((ah >>> 28) | (al << 4)) ^ ((ah << 30) | (al >>> 2)) ^ ((ah << 25) | (al >>> 7));
3111           var sigma0l = ((al >>> 28) | (ah << 4)) ^ ((al << 30) | (ah >>> 2)) ^ ((al << 25) | (ah >>> 7));
3112           var sigma1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((eh << 23) | (el >>> 9));
3113           var sigma1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((el << 23) | (eh >>> 9));
3114 
3115           // t1 = h + sigma1 + ch + K[i] + W[i]
3116           var Ki = K[i];
3117           var Kih = Ki.high;
3118           var Kil = Ki.low;
3119 
3120           var t1l = hl + sigma1l;
3121           var t1h = hh + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0);
3122           var t1l = t1l + chl;
3123           var t1h = t1h + chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0);
3124           var t1l = t1l + Kil;
3125           var t1h = t1h + Kih + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0);
3126           var t1l = t1l + Wil;
3127           var t1h = t1h + Wih + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0);
3128 
3129           // t2 = sigma0 + maj
3130           var t2l = sigma0l + majl;
3131           var t2h = sigma0h + majh + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0);
3132 
3133           // Update working variables
3134           hh = gh;
3135           hl = gl;
3136           gh = fh;
3137           gl = fl;
3138           fh = eh;
3139           fl = el;
3140           el = (dl + t1l) | 0;
3141           eh = (dh + t1h + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0;
3142           dh = ch;
3143           dl = cl;
3144           ch = bh;
3145           cl = bl;
3146           bh = ah;
3147           bl = al;
3148           al = (t1l + t2l) | 0;
3149           ah = (t1h + t2h + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0;
3150         }
3151 
3152         // Intermediate hash value
3153         H0l = H0.low = (H0l + al);
3154         H0.high = (H0h + ah + ((H0l >>> 0) < (al >>> 0) ? 1 : 0));
3155         H1l = H1.low = (H1l + bl);
3156         H1.high = (H1h + bh + ((H1l >>> 0) < (bl >>> 0) ? 1 : 0));
3157         H2l = H2.low = (H2l + cl);
3158         H2.high = (H2h + ch + ((H2l >>> 0) < (cl >>> 0) ? 1 : 0));
3159         H3l = H3.low = (H3l + dl);
3160         H3.high = (H3h + dh + ((H3l >>> 0) < (dl >>> 0) ? 1 : 0));
3161         H4l = H4.low = (H4l + el);
3162         H4.high = (H4h + eh + ((H4l >>> 0) < (el >>> 0) ? 1 : 0));
3163         H5l = H5.low = (H5l + fl);
3164         H5.high = (H5h + fh + ((H5l >>> 0) < (fl >>> 0) ? 1 : 0));
3165         H6l = H6.low = (H6l + gl);
3166         H6.high = (H6h + gh + ((H6l >>> 0) < (gl >>> 0) ? 1 : 0));
3167         H7l = H7.low = (H7l + hl);
3168         H7.high = (H7h + hh + ((H7l >>> 0) < (hl >>> 0) ? 1 : 0));
3169       },
3170 
3171       _doFinalize: function() {
3172         // Shortcuts
3173         var data = this._data;
3174         var dataWords = data.words;
3175 
3176         var nBitsTotal = this._nDataBytes * 8;
3177         var nBitsLeft = data.sigBytes * 8;
3178 
3179         // Add padding
3180         dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
3181         dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 30] = Math.floor(nBitsTotal / 0x100000000);
3182         dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 31] = nBitsTotal;
3183         data.sigBytes = dataWords.length * 4;
3184 
3185         // Hash final blocks
3186         this._process();
3187 
3188         // Convert hash to 32-bit word array before returning
3189         var hash = this._hash.toX32();
3190 
3191         // Return final computed hash
3192         return hash;
3193       },
3194 
3195       clone: function() {
3196         var clone = Hasher.clone.call(this);
3197         clone._hash = this._hash.clone();
3198 
3199         return clone;
3200       },
3201 
3202       blockSize: 1024 / 32
3203     });
3204 
3205     /**
3206      * Shortcut function to the hasher's object interface.
3207      *
3208      * @param {WordArray|string} message The message to hash.
3209      *
3210      * @return {WordArray} The hash.
3211      *
3212      * @static
3213      *
3214      * @example
3215      *
3216      *     var hash = CryptoJS.SHA512('message');
3217      *     var hash = CryptoJS.SHA512(wordArray);
3218      */
3219     C.SHA512 = Hasher._createHelper(SHA512);
3220 
3221     /**
3222      * Shortcut function to the HMAC's object interface.
3223      *
3224      * @param {WordArray|string} message The message to hash.
3225      * @param {WordArray|string} key The secret key.
3226      *
3227      * @return {WordArray} The HMAC.
3228      *
3229      * @static
3230      *
3231      * @example
3232      *
3233      *     var hmac = CryptoJS.HmacSHA512(message, key);
3234      */
3235     C.HmacSHA512 = Hasher._createHmacHelper(SHA512);
3236   }());
3237 
3238 
3239   (function() {
3240     // Shortcuts
3241     var C = CryptoJS;
3242     var C_x64 = C.x64;
3243     var X64Word = C_x64.Word;
3244     var X64WordArray = C_x64.WordArray;
3245     var C_algo = C.algo;
3246     var SHA512 = C_algo.SHA512;
3247 
3248     /**
3249      * SHA-384 hash algorithm.
3250      */
3251     var SHA384 = C_algo.SHA384 = SHA512.extend({
3252       _doReset: function() {
3253         this._hash = new X64WordArray.init([
3254           new X64Word.init(0xcbbb9d5d, 0xc1059ed8), new X64Word.init(0x629a292a, 0x367cd507),
3255           new X64Word.init(0x9159015a, 0x3070dd17), new X64Word.init(0x152fecd8, 0xf70e5939),
3256           new X64Word.init(0x67332667, 0xffc00b31), new X64Word.init(0x8eb44a87, 0x68581511),
3257           new X64Word.init(0xdb0c2e0d, 0x64f98fa7), new X64Word.init(0x47b5481d, 0xbefa4fa4)
3258         ]);
3259       },
3260 
3261       _doFinalize: function() {
3262         var hash = SHA512._doFinalize.call(this);
3263 
3264         hash.sigBytes -= 16;
3265 
3266         return hash;
3267       }
3268     });
3269 
3270     /**
3271      * Shortcut function to the hasher's object interface.
3272      *
3273      * @param {WordArray|string} message The message to hash.
3274      *
3275      * @return {WordArray} The hash.
3276      *
3277      * @static
3278      *
3279      * @example
3280      *
3281      *     var hash = CryptoJS.SHA384('message');
3282      *     var hash = CryptoJS.SHA384(wordArray);
3283      */
3284     C.SHA384 = SHA512._createHelper(SHA384);
3285 
3286     /**
3287      * Shortcut function to the HMAC's object interface.
3288      *
3289      * @param {WordArray|string} message The message to hash.
3290      * @param {WordArray|string} key The secret key.
3291      *
3292      * @return {WordArray} The HMAC.
3293      *
3294      * @static
3295      *
3296      * @example
3297      *
3298      *     var hmac = CryptoJS.HmacSHA384(message, key);
3299      */
3300     C.HmacSHA384 = SHA512._createHmacHelper(SHA384);
3301   }());
3302 
3303 
3304   /**
3305    * Cipher core components.
3306    */
3307   CryptoJS.lib.Cipher || (function(undefined) {
3308     // Shortcuts
3309     var C = CryptoJS;
3310     var C_lib = C.lib;
3311     var Base = C_lib.Base;
3312     var WordArray = C_lib.WordArray;
3313     var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;
3314     var C_enc = C.enc;
3315     var Utf8 = C_enc.Utf8;
3316     var Base64 = C_enc.Base64;
3317     var C_algo = C.algo;
3318     var EvpKDF = C_algo.EvpKDF;
3319 
3320     /**
3321      * Abstract base cipher template.
3322      *
3323      * @property {number} keySize This cipher's key size. Default: 4 (128 bits)
3324      * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)
3325      * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.
3326      * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.
3327      */
3328     var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({
3329       /**
3330        * Configuration options.
3331        *
3332        * @property {WordArray} iv The IV to use for this operation.
3333        */
3334       cfg: Base.extend(),
3335 
3336       /**
3337        * Creates this cipher in encryption mode.
3338        *
3339        * @param {WordArray} key The key.
3340        * @param {Object} cfg (Optional) The configuration options to use for this operation.
3341        *
3342        * @return {Cipher} A cipher instance.
3343        *
3344        * @static
3345        *
3346        * @example
3347        *
3348        *     var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });
3349        */
3350       createEncryptor: function(key, cfg) {
3351         return this.create(this._ENC_XFORM_MODE, key, cfg);
3352       },
3353 
3354       /**
3355        * Creates this cipher in decryption mode.
3356        *
3357        * @param {WordArray} key The key.
3358        * @param {Object} cfg (Optional) The configuration options to use for this operation.
3359        *
3360        * @return {Cipher} A cipher instance.
3361        *
3362        * @static
3363        *
3364        * @example
3365        *
3366        *     var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });
3367        */
3368       createDecryptor: function(key, cfg) {
3369         return this.create(this._DEC_XFORM_MODE, key, cfg);
3370       },
3371 
3372       /**
3373        * Initializes a newly created cipher.
3374        *
3375        * @param {number} xformMode Either the encryption or decryption transormation mode constant.
3376        * @param {WordArray} key The key.
3377        * @param {Object} cfg (Optional) The configuration options to use for this operation.
3378        *
3379        * @example
3380        *
3381        *     var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });
3382        */
3383       init: function(xformMode, key, cfg) {
3384         // Apply config defaults
3385         this.cfg = this.cfg.extend(cfg);
3386 
3387         // Store transform mode and key
3388         this._xformMode = xformMode;
3389         this._key = key;
3390 
3391         // Set initial values
3392         this.reset();
3393       },
3394 
3395       /**
3396        * Resets this cipher to its initial state.
3397        *
3398        * @example
3399        *
3400        *     cipher.reset();
3401        */
3402       reset: function() {
3403         // Reset data buffer
3404         BufferedBlockAlgorithm.reset.call(this);
3405 
3406         // Perform concrete-cipher logic
3407         this._doReset();
3408       },
3409 
3410       /**
3411        * Adds data to be encrypted or decrypted.
3412        *
3413        * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.
3414        *
3415        * @return {WordArray} The data after processing.
3416        *
3417        * @example
3418        *
3419        *     var encrypted = cipher.process('data');
3420        *     var encrypted = cipher.process(wordArray);
3421        */
3422       process: function(dataUpdate) {
3423         // Append
3424         this._append(dataUpdate);
3425 
3426         // Process available blocks
3427         return this._process();
3428       },
3429 
3430       /**
3431        * Finalizes the encryption or decryption process.
3432        * Note that the finalize operation is effectively a destructive, read-once operation.
3433        *
3434        * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.
3435        *
3436        * @return {WordArray} The data after final processing.
3437        *
3438        * @example
3439        *
3440        *     var encrypted = cipher.finalize();
3441        *     var encrypted = cipher.finalize('data');
3442        *     var encrypted = cipher.finalize(wordArray);
3443        */
3444       finalize: function(dataUpdate) {
3445         // Final data update
3446         if (dataUpdate) {
3447           this._append(dataUpdate);
3448         }
3449 
3450         // Perform concrete-cipher logic
3451         var finalProcessedData = this._doFinalize();
3452 
3453         return finalProcessedData;
3454       },
3455 
3456       keySize: 128 / 32,
3457 
3458       ivSize: 128 / 32,
3459 
3460       _ENC_XFORM_MODE: 1,
3461 
3462       _DEC_XFORM_MODE: 2,
3463 
3464       /**
3465        * Creates shortcut functions to a cipher's object interface.
3466        *
3467        * @param {Cipher} cipher The cipher to create a helper for.
3468        *
3469        * @return {Object} An object with encrypt and decrypt shortcut functions.
3470        *
3471        * @static
3472        *
3473        * @example
3474        *
3475        *     var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);
3476        */
3477       _createHelper: (function() {
3478         function selectCipherStrategy(key) {
3479           if (typeof key == 'string') {
3480             return PasswordBasedCipher;
3481           } else {
3482             return SerializableCipher;
3483           }
3484         }
3485 
3486         return function(cipher) {
3487           return {
3488             encrypt: function(message, key, cfg) {
3489               return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);
3490             },
3491 
3492             decrypt: function(ciphertext, key, cfg) {
3493               return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);
3494             }
3495           };
3496         };
3497       }())
3498     });
3499 
3500     /**
3501      * Abstract base stream cipher template.
3502      *
3503      * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)
3504      */
3505     var StreamCipher = C_lib.StreamCipher = Cipher.extend({
3506       _doFinalize: function() {
3507         // Process partial blocks
3508         var finalProcessedBlocks = this._process(!!'flush');
3509 
3510         return finalProcessedBlocks;
3511       },
3512 
3513       blockSize: 1
3514     });
3515 
3516     /**
3517      * Mode namespace.
3518      */
3519     var C_mode = C.mode = {};
3520 
3521     /**
3522      * Abstract base block cipher mode template.
3523      */
3524     var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({
3525       /**
3526        * Creates this mode for encryption.
3527        *
3528        * @param {Cipher} cipher A block cipher instance.
3529        * @param {Array} iv The IV words.
3530        *
3531        * @static
3532        *
3533        * @example
3534        *
3535        *     var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);
3536        */
3537       createEncryptor: function(cipher, iv) {
3538         return this.Encryptor.create(cipher, iv);
3539       },
3540 
3541       /**
3542        * Creates this mode for decryption.
3543        *
3544        * @param {Cipher} cipher A block cipher instance.
3545        * @param {Array} iv The IV words.
3546        *
3547        * @static
3548        *
3549        * @example
3550        *
3551        *     var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);
3552        */
3553       createDecryptor: function(cipher, iv) {
3554         return this.Decryptor.create(cipher, iv);
3555       },
3556 
3557       /**
3558        * Initializes a newly created mode.
3559        *
3560        * @param {Cipher} cipher A block cipher instance.
3561        * @param {Array} iv The IV words.
3562        *
3563        * @example
3564        *
3565        *     var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);
3566        */
3567       init: function(cipher, iv) {
3568         this._cipher = cipher;
3569         this._iv = iv;
3570       }
3571     });
3572 
3573     /**
3574      * Cipher Block Chaining mode.
3575      */
3576     var CBC = C_mode.CBC = (function() {
3577       /**
3578        * Abstract base CBC mode.
3579        */
3580       var CBC = BlockCipherMode.extend();
3581 
3582       /**
3583        * CBC encryptor.
3584        */
3585       CBC.Encryptor = CBC.extend({
3586         /**
3587          * Processes the data block at offset.
3588          *
3589          * @param {Array} words The data words to operate on.
3590          * @param {number} offset The offset where the block starts.
3591          *
3592          * @example
3593          *
3594          *     mode.processBlock(data.words, offset);
3595          */
3596         processBlock: function(words, offset) {
3597           // Shortcuts
3598           var cipher = this._cipher;
3599           var blockSize = cipher.blockSize;
3600 
3601           // XOR and encrypt
3602           xorBlock.call(this, words, offset, blockSize);
3603           cipher.encryptBlock(words, offset);
3604 
3605           // Remember this block to use with next block
3606           this._prevBlock = words.slice(offset, offset + blockSize);
3607         }
3608       });
3609 
3610       /**
3611        * CBC decryptor.
3612        */
3613       CBC.Decryptor = CBC.extend({
3614         /**
3615          * Processes the data block at offset.
3616          *
3617          * @param {Array} words The data words to operate on.
3618          * @param {number} offset The offset where the block starts.
3619          *
3620          * @example
3621          *
3622          *     mode.processBlock(data.words, offset);
3623          */
3624         processBlock: function(words, offset) {
3625           // Shortcuts
3626           var cipher = this._cipher;
3627           var blockSize = cipher.blockSize;
3628 
3629           // Remember this block to use with next block
3630           var thisBlock = words.slice(offset, offset + blockSize);
3631 
3632           // Decrypt and XOR
3633           cipher.decryptBlock(words, offset);
3634           xorBlock.call(this, words, offset, blockSize);
3635 
3636           // This block becomes the previous block
3637           this._prevBlock = thisBlock;
3638         }
3639       });
3640 
3641       function xorBlock(words, offset, blockSize) {
3642         var block;
3643 
3644         // Shortcut
3645         var iv = this._iv;
3646 
3647         // Choose mixing block
3648         if (iv) {
3649           block = iv;
3650 
3651           // Remove IV for subsequent blocks
3652           this._iv = undefined;
3653         } else {
3654           block = this._prevBlock;
3655         }
3656 
3657         // XOR blocks
3658         for (var i = 0; i < blockSize; i++) {
3659           words[offset + i] ^= block[i];
3660         }
3661       }
3662 
3663       return CBC;
3664     }());
3665 
3666     /**
3667      * Padding namespace.
3668      */
3669     var C_pad = C.pad = {};
3670 
3671     /**
3672      * PKCS #5/7 padding strategy.
3673      */
3674     var Pkcs7 = C_pad.Pkcs7 = {
3675       /**
3676        * Pads data using the algorithm defined in PKCS #5/7.
3677        *
3678        * @param {WordArray} data The data to pad.
3679        * @param {number} blockSize The multiple that the data should be padded to.
3680        *
3681        * @static
3682        *
3683        * @example
3684        *
3685        *     CryptoJS.pad.Pkcs7.pad(wordArray, 4);
3686        */
3687       pad: function(data, blockSize) {
3688         // Shortcut
3689         var blockSizeBytes = blockSize * 4;
3690 
3691         // Count padding bytes
3692         var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
3693 
3694         // Create padding word
3695         var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;
3696 
3697         // Create padding
3698         var paddingWords = [];
3699         for (var i = 0; i < nPaddingBytes; i += 4) {
3700           paddingWords.push(paddingWord);
3701         }
3702         var padding = WordArray.create(paddingWords, nPaddingBytes);
3703 
3704         // Add padding
3705         data.concat(padding);
3706       },
3707 
3708       /**
3709        * Unpads data that had been padded using the algorithm defined in PKCS #5/7.
3710        *
3711        * @param {WordArray} data The data to unpad.
3712        *
3713        * @static
3714        *
3715        * @example
3716        *
3717        *     CryptoJS.pad.Pkcs7.unpad(wordArray);
3718        */
3719       unpad: function(data) {
3720         // Get number of padding bytes from last byte
3721         var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
3722 
3723         // Remove padding
3724         data.sigBytes -= nPaddingBytes;
3725       }
3726     };
3727 
3728     /**
3729      * Abstract base block cipher template.
3730      *
3731      * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)
3732      */
3733     var BlockCipher = C_lib.BlockCipher = Cipher.extend({
3734       /**
3735        * Configuration options.
3736        *
3737        * @property {Mode} mode The block mode to use. Default: CBC
3738        * @property {Padding} padding The padding strategy to use. Default: Pkcs7
3739        */
3740       cfg: Cipher.cfg.extend({
3741         mode: CBC,
3742         padding: Pkcs7
3743       }),
3744 
3745       reset: function() {
3746         var modeCreator;
3747 
3748         // Reset cipher
3749         Cipher.reset.call(this);
3750 
3751         // Shortcuts
3752         var cfg = this.cfg;
3753         var iv = cfg.iv;
3754         var mode = cfg.mode;
3755 
3756         // Reset block mode
3757         if (this._xformMode == this._ENC_XFORM_MODE) {
3758           modeCreator = mode.createEncryptor;
3759         } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
3760           modeCreator = mode.createDecryptor;
3761           // Keep at least one block in the buffer for unpadding
3762           this._minBufferSize = 1;
3763         }
3764 
3765         if (this._mode && this._mode.__creator == modeCreator) {
3766           this._mode.init(this, iv && iv.words);
3767         } else {
3768           this._mode = modeCreator.call(mode, this, iv && iv.words);
3769           this._mode.__creator = modeCreator;
3770         }
3771       },
3772 
3773       _doProcessBlock: function(words, offset) {
3774         this._mode.processBlock(words, offset);
3775       },
3776 
3777       _doFinalize: function() {
3778         var finalProcessedBlocks;
3779 
3780         // Shortcut
3781         var padding = this.cfg.padding;
3782 
3783         // Finalize
3784         if (this._xformMode == this._ENC_XFORM_MODE) {
3785           // Pad data
3786           padding.pad(this._data, this.blockSize);
3787 
3788           // Process final blocks
3789           finalProcessedBlocks = this._process(!!'flush');
3790         } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
3791           // Process final blocks
3792           finalProcessedBlocks = this._process(!!'flush');
3793 
3794           // Unpad data
3795           padding.unpad(finalProcessedBlocks);
3796         }
3797 
3798         return finalProcessedBlocks;
3799       },
3800 
3801       blockSize: 128 / 32
3802     });
3803 
3804     /**
3805      * A collection of cipher parameters.
3806      *
3807      * @property {WordArray} ciphertext The raw ciphertext.
3808      * @property {WordArray} key The key to this ciphertext.
3809      * @property {WordArray} iv The IV used in the ciphering operation.
3810      * @property {WordArray} salt The salt used with a key derivation function.
3811      * @property {Cipher} algorithm The cipher algorithm.
3812      * @property {Mode} mode The block mode used in the ciphering operation.
3813      * @property {Padding} padding The padding scheme used in the ciphering operation.
3814      * @property {number} blockSize The block size of the cipher.
3815      * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.
3816      */
3817     var CipherParams = C_lib.CipherParams = Base.extend({
3818       /**
3819        * Initializes a newly created cipher params object.
3820        *
3821        * @param {Object} cipherParams An object with any of the possible cipher parameters.
3822        *
3823        * @example
3824        *
3825        *     var cipherParams = CryptoJS.lib.CipherParams.create({
3826        *         ciphertext: ciphertextWordArray,
3827        *         key: keyWordArray,
3828        *         iv: ivWordArray,
3829        *         salt: saltWordArray,
3830        *         algorithm: CryptoJS.algo.AES,
3831        *         mode: CryptoJS.mode.CBC,
3832        *         padding: CryptoJS.pad.PKCS7,
3833        *         blockSize: 4,
3834        *         formatter: CryptoJS.format.OpenSSL
3835        *     });
3836        */
3837       init: function(cipherParams) {
3838         this.mixIn(cipherParams);
3839       },
3840 
3841       /**
3842        * Converts this cipher params object to a string.
3843        *
3844        * @param {Format} formatter (Optional) The formatting strategy to use.
3845        *
3846        * @return {string} The stringified cipher params.
3847        *
3848        * @throws Error If neither the formatter nor the default formatter is set.
3849        *
3850        * @example
3851        *
3852        *     var string = cipherParams + '';
3853        *     var string = cipherParams.toString();
3854        *     var string = cipherParams.toString(CryptoJS.format.OpenSSL);
3855        */
3856       toString: function(formatter) {
3857         return (formatter || this.formatter).stringify(this);
3858       }
3859     });
3860 
3861     /**
3862      * Format namespace.
3863      */
3864     var C_format = C.format = {};
3865 
3866     /**
3867      * OpenSSL formatting strategy.
3868      */
3869     var OpenSSLFormatter = C_format.OpenSSL = {
3870       /**
3871        * Converts a cipher params object to an OpenSSL-compatible string.
3872        *
3873        * @param {CipherParams} cipherParams The cipher params object.
3874        *
3875        * @return {string} The OpenSSL-compatible string.
3876        *
3877        * @static
3878        *
3879        * @example
3880        *
3881        *     var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);
3882        */
3883       stringify: function(cipherParams) {
3884         var wordArray;
3885 
3886         // Shortcuts
3887         var ciphertext = cipherParams.ciphertext;
3888         var salt = cipherParams.salt;
3889 
3890         // Format
3891         if (salt) {
3892           wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
3893         } else {
3894           wordArray = ciphertext;
3895         }
3896 
3897         return wordArray.toString(Base64);
3898       },
3899 
3900       /**
3901        * Converts an OpenSSL-compatible string to a cipher params object.
3902        *
3903        * @param {string} openSSLStr The OpenSSL-compatible string.
3904        *
3905        * @return {CipherParams} The cipher params object.
3906        *
3907        * @static
3908        *
3909        * @example
3910        *
3911        *     var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);
3912        */
3913       parse: function(openSSLStr) {
3914         var salt;
3915 
3916         // Parse base64
3917         var ciphertext = Base64.parse(openSSLStr);
3918 
3919         // Shortcut
3920         var ciphertextWords = ciphertext.words;
3921 
3922         // Test for salt
3923         if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {
3924           // Extract salt
3925           salt = WordArray.create(ciphertextWords.slice(2, 4));
3926 
3927           // Remove salt from ciphertext
3928           ciphertextWords.splice(0, 4);
3929           ciphertext.sigBytes -= 16;
3930         }
3931 
3932         return CipherParams.create({
3933           ciphertext: ciphertext,
3934           salt: salt
3935         });
3936       }
3937     };
3938 
3939     /**
3940      * A cipher wrapper that returns ciphertext as a serializable cipher params object.
3941      */
3942     var SerializableCipher = C_lib.SerializableCipher = Base.extend({
3943       /**
3944        * Configuration options.
3945        *
3946        * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL
3947        */
3948       cfg: Base.extend({
3949         format: OpenSSLFormatter
3950       }),
3951 
3952       /**
3953        * Encrypts a message.
3954        *
3955        * @param {Cipher} cipher The cipher algorithm to use.
3956        * @param {WordArray|string} message The message to encrypt.
3957        * @param {WordArray} key The key.
3958        * @param {Object} cfg (Optional) The configuration options to use for this operation.
3959        *
3960        * @return {CipherParams} A cipher params object.
3961        *
3962        * @static
3963        *
3964        * @example
3965        *
3966        *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);
3967        *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });
3968        *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });
3969        */
3970       encrypt: function(cipher, message, key, cfg) {
3971         // Apply config defaults
3972         cfg = this.cfg.extend(cfg);
3973 
3974         // Encrypt
3975         var encryptor = cipher.createEncryptor(key, cfg);
3976         var ciphertext = encryptor.finalize(message);
3977 
3978         // Shortcut
3979         var cipherCfg = encryptor.cfg;
3980 
3981         // Create and return serializable cipher params
3982         return CipherParams.create({
3983           ciphertext: ciphertext,
3984           key: key,
3985           iv: cipherCfg.iv,
3986           algorithm: cipher,
3987           mode: cipherCfg.mode,
3988           padding: cipherCfg.padding,
3989           blockSize: cipher.blockSize,
3990           formatter: cfg.format
3991         });
3992       },
3993 
3994       /**
3995        * Decrypts serialized ciphertext.
3996        *
3997        * @param {Cipher} cipher The cipher algorithm to use.
3998        * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
3999        * @param {WordArray} key The key.
4000        * @param {Object} cfg (Optional) The configuration options to use for this operation.
4001        *
4002        * @return {WordArray} The plaintext.
4003        *
4004        * @static
4005        *
4006        * @example
4007        *
4008        *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });
4009        *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });
4010        */
4011       decrypt: function(cipher, ciphertext, key, cfg) {
4012         // Apply config defaults
4013         cfg = this.cfg.extend(cfg);
4014 
4015         // Convert string to CipherParams
4016         ciphertext = this._parse(ciphertext, cfg.format);
4017 
4018         // Decrypt
4019         var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);
4020 
4021         return plaintext;
4022       },
4023 
4024       /**
4025        * Converts serialized ciphertext to CipherParams,
4026        * else assumed CipherParams already and returns ciphertext unchanged.
4027        *
4028        * @param {CipherParams|string} ciphertext The ciphertext.
4029        * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.
4030        *
4031        * @return {CipherParams} The unserialized ciphertext.
4032        *
4033        * @static
4034        *
4035        * @example
4036        *
4037        *     var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);
4038        */
4039       _parse: function(ciphertext, format) {
4040         if (typeof ciphertext == 'string') {
4041           return format.parse(ciphertext, this);
4042         } else {
4043           return ciphertext;
4044         }
4045       }
4046     });
4047 
4048     /**
4049      * Key derivation function namespace.
4050      */
4051     var C_kdf = C.kdf = {};
4052 
4053     /**
4054      * OpenSSL key derivation function.
4055      */
4056     var OpenSSLKdf = C_kdf.OpenSSL = {
4057       /**
4058        * Derives a key and IV from a password.
4059        *
4060        * @param {string} password The password to derive from.
4061        * @param {number} keySize The size in words of the key to generate.
4062        * @param {number} ivSize The size in words of the IV to generate.
4063        * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.
4064        *
4065        * @return {CipherParams} A cipher params object with the key, IV, and salt.
4066        *
4067        * @static
4068        *
4069        * @example
4070        *
4071        *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);
4072        *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');
4073        */
4074       execute: function(password, keySize, ivSize, salt) {
4075         // Generate random salt
4076         if (!salt) {
4077           salt = WordArray.random(64 / 8);
4078         }
4079 
4080         // Derive key and IV
4081         var key = EvpKDF.create({
4082           keySize: keySize + ivSize
4083         }).compute(password, salt);
4084 
4085         // Separate key and IV
4086         var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);
4087         key.sigBytes = keySize * 4;
4088 
4089         // Return params
4090         return CipherParams.create({
4091           key: key,
4092           iv: iv,
4093           salt: salt
4094         });
4095       }
4096     };
4097 
4098     /**
4099      * A serializable cipher wrapper that derives the key from a password,
4100      * and returns ciphertext as a serializable cipher params object.
4101      */
4102     var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({
4103       /**
4104        * Configuration options.
4105        *
4106        * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL
4107        */
4108       cfg: SerializableCipher.cfg.extend({
4109         kdf: OpenSSLKdf
4110       }),
4111 
4112       /**
4113        * Encrypts a message using a password.
4114        *
4115        * @param {Cipher} cipher The cipher algorithm to use.
4116        * @param {WordArray|string} message The message to encrypt.
4117        * @param {string} password The password.
4118        * @param {Object} cfg (Optional) The configuration options to use for this operation.
4119        *
4120        * @return {CipherParams} A cipher params object.
4121        *
4122        * @static
4123        *
4124        * @example
4125        *
4126        *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');
4127        *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });
4128        */
4129       encrypt: function(cipher, message, password, cfg) {
4130         // Apply config defaults
4131         cfg = this.cfg.extend(cfg);
4132 
4133         // Derive key and other params
4134         var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);
4135 
4136         // Add IV to config
4137         cfg.iv = derivedParams.iv;
4138 
4139         // Encrypt
4140         var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);
4141 
4142         // Mix in derived params
4143         ciphertext.mixIn(derivedParams);
4144 
4145         return ciphertext;
4146       },
4147 
4148       /**
4149        * Decrypts serialized ciphertext using a password.
4150        *
4151        * @param {Cipher} cipher The cipher algorithm to use.
4152        * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
4153        * @param {string} password The password.
4154        * @param {Object} cfg (Optional) The configuration options to use for this operation.
4155        *
4156        * @return {WordArray} The plaintext.
4157        *
4158        * @static
4159        *
4160        * @example
4161        *
4162        *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });
4163        *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });
4164        */
4165       decrypt: function(cipher, ciphertext, password, cfg) {
4166         // Apply config defaults
4167         cfg = this.cfg.extend(cfg);
4168 
4169         // Convert string to CipherParams
4170         ciphertext = this._parse(ciphertext, cfg.format);
4171 
4172         // Derive key and other params
4173         var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);
4174 
4175         // Add IV to config
4176         cfg.iv = derivedParams.iv;
4177 
4178         // Decrypt
4179         var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);
4180 
4181         return plaintext;
4182       }
4183     });
4184   }());
4185 
4186 
4187   /**
4188    * Cipher Feedback block mode.
4189    */
4190   CryptoJS.mode.CFB = (function() {
4191     var CFB = CryptoJS.lib.BlockCipherMode.extend();
4192 
4193     CFB.Encryptor = CFB.extend({
4194       processBlock: function(words, offset) {
4195         // Shortcuts
4196         var cipher = this._cipher;
4197         var blockSize = cipher.blockSize;
4198 
4199         generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
4200 
4201         // Remember this block to use with next block
4202         this._prevBlock = words.slice(offset, offset + blockSize);
4203       }
4204     });
4205 
4206     CFB.Decryptor = CFB.extend({
4207       processBlock: function(words, offset) {
4208         // Shortcuts
4209         var cipher = this._cipher;
4210         var blockSize = cipher.blockSize;
4211 
4212         // Remember this block to use with next block
4213         var thisBlock = words.slice(offset, offset + blockSize);
4214 
4215         generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
4216 
4217         // This block becomes the previous block
4218         this._prevBlock = thisBlock;
4219       }
4220     });
4221 
4222     function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) {
4223       var keystream;
4224 
4225       // Shortcut
4226       var iv = this._iv;
4227 
4228       // Generate keystream
4229       if (iv) {
4230         keystream = iv.slice(0);
4231 
4232         // Remove IV for subsequent blocks
4233         this._iv = undefined;
4234       } else {
4235         keystream = this._prevBlock;
4236       }
4237       cipher.encryptBlock(keystream, 0);
4238 
4239       // Encrypt
4240       for (var i = 0; i < blockSize; i++) {
4241         words[offset + i] ^= keystream[i];
4242       }
4243     }
4244 
4245     return CFB;
4246   }());
4247 
4248 
4249   /**
4250    * Electronic Codebook block mode.
4251    */
4252   CryptoJS.mode.ECB = (function() {
4253     var ECB = CryptoJS.lib.BlockCipherMode.extend();
4254 
4255     ECB.Encryptor = ECB.extend({
4256       processBlock: function(words, offset) {
4257         this._cipher.encryptBlock(words, offset);
4258       }
4259     });
4260 
4261     ECB.Decryptor = ECB.extend({
4262       processBlock: function(words, offset) {
4263         this._cipher.decryptBlock(words, offset);
4264       }
4265     });
4266 
4267     return ECB;
4268   }());
4269 
4270 
4271   /**
4272    * ANSI X.923 padding strategy.
4273    */
4274   CryptoJS.pad.AnsiX923 = {
4275     pad: function(data, blockSize) {
4276       // Shortcuts
4277       var dataSigBytes = data.sigBytes;
4278       var blockSizeBytes = blockSize * 4;
4279 
4280       // Count padding bytes
4281       var nPaddingBytes = blockSizeBytes - dataSigBytes % blockSizeBytes;
4282 
4283       // Compute last byte position
4284       var lastBytePos = dataSigBytes + nPaddingBytes - 1;
4285 
4286       // Pad
4287       data.clamp();
4288       data.words[lastBytePos >>> 2] |= nPaddingBytes << (24 - (lastBytePos % 4) * 8);
4289       data.sigBytes += nPaddingBytes;
4290     },
4291 
4292     unpad: function(data) {
4293       // Get number of padding bytes from last byte
4294       var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
4295 
4296       // Remove padding
4297       data.sigBytes -= nPaddingBytes;
4298     }
4299   };
4300 
4301 
4302   /**
4303    * ISO 10126 padding strategy.
4304    */
4305   CryptoJS.pad.Iso10126 = {
4306     pad: function(data, blockSize) {
4307       // Shortcut
4308       var blockSizeBytes = blockSize * 4;
4309 
4310       // Count padding bytes
4311       var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
4312 
4313       // Pad
4314       data.concat(CryptoJS.lib.WordArray.random(nPaddingBytes - 1)).
4315       concat(CryptoJS.lib.WordArray.create([nPaddingBytes << 24], 1));
4316     },
4317 
4318     unpad: function(data) {
4319       // Get number of padding bytes from last byte
4320       var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
4321 
4322       // Remove padding
4323       data.sigBytes -= nPaddingBytes;
4324     }
4325   };
4326 
4327 
4328   /**
4329    * ISO/IEC 9797-1 Padding Method 2.
4330    */
4331   CryptoJS.pad.Iso97971 = {
4332     pad: function(data, blockSize) {
4333       // Add 0x80 byte
4334       data.concat(CryptoJS.lib.WordArray.create([0x80000000], 1));
4335 
4336       // Zero pad the rest
4337       CryptoJS.pad.ZeroPadding.pad(data, blockSize);
4338     },
4339 
4340     unpad: function(data) {
4341       // Remove zero padding
4342       CryptoJS.pad.ZeroPadding.unpad(data);
4343 
4344       // Remove one more byte -- the 0x80 byte
4345       data.sigBytes--;
4346     }
4347   };
4348 
4349 
4350   /**
4351    * Output Feedback block mode.
4352    */
4353   CryptoJS.mode.OFB = (function() {
4354     var OFB = CryptoJS.lib.BlockCipherMode.extend();
4355 
4356     var Encryptor = OFB.Encryptor = OFB.extend({
4357       processBlock: function(words, offset) {
4358         // Shortcuts
4359         var cipher = this._cipher
4360         var blockSize = cipher.blockSize;
4361         var iv = this._iv;
4362         var keystream = this._keystream;
4363 
4364         // Generate keystream
4365         if (iv) {
4366           keystream = this._keystream = iv.slice(0);
4367 
4368           // Remove IV for subsequent blocks
4369           this._iv = undefined;
4370         }
4371         cipher.encryptBlock(keystream, 0);
4372 
4373         // Encrypt
4374         for (var i = 0; i < blockSize; i++) {
4375           words[offset + i] ^= keystream[i];
4376         }
4377       }
4378     });
4379 
4380     OFB.Decryptor = Encryptor;
4381 
4382     return OFB;
4383   }());
4384 
4385 
4386   /**
4387    * A noop padding strategy.
4388    */
4389   CryptoJS.pad.NoPadding = {
4390     pad: function() {},
4391 
4392     unpad: function() {}
4393   };
4394 
4395 
4396   (function(undefined) {
4397     // Shortcuts
4398     var C = CryptoJS;
4399     var C_lib = C.lib;
4400     var CipherParams = C_lib.CipherParams;
4401     var C_enc = C.enc;
4402     var Hex = C_enc.Hex;
4403     var C_format = C.format;
4404 
4405     var HexFormatter = C_format.Hex = {
4406       /**
4407        * Converts the ciphertext of a cipher params object to a hexadecimally encoded string.
4408        *
4409        * @param {CipherParams} cipherParams The cipher params object.
4410        *
4411        * @return {string} The hexadecimally encoded string.
4412        *
4413        * @static
4414        *
4415        * @example
4416        *
4417        *     var hexString = CryptoJS.format.Hex.stringify(cipherParams);
4418        */
4419       stringify: function(cipherParams) {
4420         return cipherParams.ciphertext.toString(Hex);
4421       },
4422 
4423       /**
4424        * Converts a hexadecimally encoded ciphertext string to a cipher params object.
4425        *
4426        * @param {string} input The hexadecimally encoded string.
4427        *
4428        * @return {CipherParams} The cipher params object.
4429        *
4430        * @static
4431        *
4432        * @example
4433        *
4434        *     var cipherParams = CryptoJS.format.Hex.parse(hexString);
4435        */
4436       parse: function(input) {
4437         var ciphertext = Hex.parse(input);
4438         return CipherParams.create({
4439           ciphertext: ciphertext
4440         });
4441       }
4442     };
4443   }());
4444 
4445 
4446   (function() {
4447     // Shortcuts
4448     var C = CryptoJS;
4449     var C_lib = C.lib;
4450     var BlockCipher = C_lib.BlockCipher;
4451     var C_algo = C.algo;
4452 
4453     // Lookup tables
4454     var SBOX = [];
4455     var INV_SBOX = [];
4456     var SUB_MIX_0 = [];
4457     var SUB_MIX_1 = [];
4458     var SUB_MIX_2 = [];
4459     var SUB_MIX_3 = [];
4460     var INV_SUB_MIX_0 = [];
4461     var INV_SUB_MIX_1 = [];
4462     var INV_SUB_MIX_2 = [];
4463     var INV_SUB_MIX_3 = [];
4464 
4465     // Compute lookup tables
4466     (function() {
4467       // Compute double table
4468       var d = [];
4469       for (var i = 0; i < 256; i++) {
4470         if (i < 128) {
4471           d[i] = i << 1;
4472         } else {
4473           d[i] = (i << 1) ^ 0x11b;
4474         }
4475       }
4476 
4477       // Walk GF(2^8)
4478       var x = 0;
4479       var xi = 0;
4480       for (var i = 0; i < 256; i++) {
4481         // Compute sbox
4482         var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
4483         sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
4484         SBOX[x] = sx;
4485         INV_SBOX[sx] = x;
4486 
4487         // Compute multiplication
4488         var x2 = d[x];
4489         var x4 = d[x2];
4490         var x8 = d[x4];
4491 
4492         // Compute sub bytes, mix columns tables
4493         var t = (d[sx] * 0x101) ^ (sx * 0x1010100);
4494         SUB_MIX_0[x] = (t << 24) | (t >>> 8);
4495         SUB_MIX_1[x] = (t << 16) | (t >>> 16);
4496         SUB_MIX_2[x] = (t << 8) | (t >>> 24);
4497         SUB_MIX_3[x] = t;
4498 
4499         // Compute inv sub bytes, inv mix columns tables
4500         var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
4501         INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8);
4502         INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16);
4503         INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24);
4504         INV_SUB_MIX_3[sx] = t;
4505 
4506         // Compute next counter
4507         if (!x) {
4508           x = xi = 1;
4509         } else {
4510           x = x2 ^ d[d[d[x8 ^ x2]]];
4511           xi ^= d[d[xi]];
4512         }
4513       }
4514     }());
4515 
4516     // Precomputed Rcon lookup
4517     var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
4518 
4519     /**
4520      * AES block cipher algorithm.
4521      */
4522     var AES = C_algo.AES = BlockCipher.extend({
4523       _doReset: function() {
4524         var t;
4525 
4526         // Skip reset of nRounds has been set before and key did not change
4527         if (this._nRounds && this._keyPriorReset === this._key) {
4528           return;
4529         }
4530 
4531         // Shortcuts
4532         var key = this._keyPriorReset = this._key;
4533         var keyWords = key.words;
4534         var keySize = key.sigBytes / 4;
4535 
4536         // Compute number of rounds
4537         var nRounds = this._nRounds = keySize + 6;
4538 
4539         // Compute number of key schedule rows
4540         var ksRows = (nRounds + 1) * 4;
4541 
4542         // Compute key schedule
4543         var keySchedule = this._keySchedule = [];
4544         for (var ksRow = 0; ksRow < ksRows; ksRow++) {
4545           if (ksRow < keySize) {
4546             keySchedule[ksRow] = keyWords[ksRow];
4547           } else {
4548             t = keySchedule[ksRow - 1];
4549 
4550             if (!(ksRow % keySize)) {
4551               // Rot word
4552               t = (t << 8) | (t >>> 24);
4553 
4554               // Sub word
4555               t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
4556 
4557               // Mix Rcon
4558               t ^= RCON[(ksRow / keySize) | 0] << 24;
4559             } else if (keySize > 6 && ksRow % keySize == 4) {
4560               // Sub word
4561               t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
4562             }
4563 
4564             keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;
4565           }
4566         }
4567 
4568         // Compute inv key schedule
4569         var invKeySchedule = this._invKeySchedule = [];
4570         for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) {
4571           var ksRow = ksRows - invKsRow;
4572 
4573           if (invKsRow % 4) {
4574             var t = keySchedule[ksRow];
4575           } else {
4576             var t = keySchedule[ksRow - 4];
4577           }
4578 
4579           if (invKsRow < 4 || ksRow <= 4) {
4580             invKeySchedule[invKsRow] = t;
4581           } else {
4582             invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^
4583               INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]];
4584           }
4585         }
4586       },
4587 
4588       encryptBlock: function(M, offset) {
4589         this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);
4590       },
4591 
4592       decryptBlock: function(M, offset) {
4593         // Swap 2nd and 4th rows
4594         var t = M[offset + 1];
4595         M[offset + 1] = M[offset + 3];
4596         M[offset + 3] = t;
4597 
4598         this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);
4599 
4600         // Inv swap 2nd and 4th rows
4601         var t = M[offset + 1];
4602         M[offset + 1] = M[offset + 3];
4603         M[offset + 3] = t;
4604       },
4605 
4606       _doCryptBlock: function(M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {
4607         // Shortcut
4608         var nRounds = this._nRounds;
4609 
4610         // Get input, add round key
4611         var s0 = M[offset] ^ keySchedule[0];
4612         var s1 = M[offset + 1] ^ keySchedule[1];
4613         var s2 = M[offset + 2] ^ keySchedule[2];
4614         var s3 = M[offset + 3] ^ keySchedule[3];
4615 
4616         // Key schedule row counter
4617         var ksRow = 4;
4618 
4619         // Rounds
4620         for (var round = 1; round < nRounds; round++) {
4621           // Shift rows, sub bytes, mix columns, add round key
4622           var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++];
4623           var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++];
4624           var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++];
4625           var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++];
4626 
4627           // Update state
4628           s0 = t0;
4629           s1 = t1;
4630           s2 = t2;
4631           s3 = t3;
4632         }
4633 
4634         // Shift rows, sub bytes, add round key
4635         var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];
4636         var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];
4637         var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];
4638         var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];
4639 
4640         // Set output
4641         M[offset] = t0;
4642         M[offset + 1] = t1;
4643         M[offset + 2] = t2;
4644         M[offset + 3] = t3;
4645       },
4646 
4647       keySize: 256 / 32
4648     });
4649 
4650     /**
4651      * Shortcut functions to the cipher's object interface.
4652      *
4653      * @example
4654      *
4655      *     var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);
4656      *     var plaintext  = CryptoJS.AES.decrypt(ciphertext, key, cfg);
4657      */
4658     C.AES = BlockCipher._createHelper(AES);
4659   }());
4660 
4661 
4662   (function() {
4663     // Shortcuts
4664     var C = CryptoJS;
4665     var C_lib = C.lib;
4666     var WordArray = C_lib.WordArray;
4667     var BlockCipher = C_lib.BlockCipher;
4668     var C_algo = C.algo;
4669 
4670     // Permuted Choice 1 constants
4671     var PC1 = [
4672       57, 49, 41, 33, 25, 17, 9, 1,
4673       58, 50, 42, 34, 26, 18, 10, 2,
4674       59, 51, 43, 35, 27, 19, 11, 3,
4675       60, 52, 44, 36, 63, 55, 47, 39,
4676       31, 23, 15, 7, 62, 54, 46, 38,
4677       30, 22, 14, 6, 61, 53, 45, 37,
4678       29, 21, 13, 5, 28, 20, 12, 4
4679     ];
4680 
4681     // Permuted Choice 2 constants
4682     var PC2 = [
4683       14, 17, 11, 24, 1, 5,
4684       3, 28, 15, 6, 21, 10,
4685       23, 19, 12, 4, 26, 8,
4686       16, 7, 27, 20, 13, 2,
4687       41, 52, 31, 37, 47, 55,
4688       30, 40, 51, 45, 33, 48,
4689       44, 49, 39, 56, 34, 53,
4690       46, 42, 50, 36, 29, 32
4691     ];
4692 
4693     // Cumulative bit shift constants
4694     var BIT_SHIFTS = [1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28];
4695 
4696     // SBOXes and round permutation constants
4697     var SBOX_P = [{
4698         0x0: 0x808200,
4699         0x10000000: 0x8000,
4700         0x20000000: 0x808002,
4701         0x30000000: 0x2,
4702         0x40000000: 0x200,
4703         0x50000000: 0x808202,
4704         0x60000000: 0x800202,
4705         0x70000000: 0x800000,
4706         0x80000000: 0x202,
4707         0x90000000: 0x800200,
4708         0xa0000000: 0x8200,
4709         0xb0000000: 0x808000,
4710         0xc0000000: 0x8002,
4711         0xd0000000: 0x800002,
4712         0xe0000000: 0x0,
4713         0xf0000000: 0x8202,
4714         0x8000000: 0x0,
4715         0x18000000: 0x808202,
4716         0x28000000: 0x8202,
4717         0x38000000: 0x8000,
4718         0x48000000: 0x808200,
4719         0x58000000: 0x200,
4720         0x68000000: 0x808002,
4721         0x78000000: 0x2,
4722         0x88000000: 0x800200,
4723         0x98000000: 0x8200,
4724         0xa8000000: 0x808000,
4725         0xb8000000: 0x800202,
4726         0xc8000000: 0x800002,
4727         0xd8000000: 0x8002,
4728         0xe8000000: 0x202,
4729         0xf8000000: 0x800000,
4730         0x1: 0x8000,
4731         0x10000001: 0x2,
4732         0x20000001: 0x808200,
4733         0x30000001: 0x800000,
4734         0x40000001: 0x808002,
4735         0x50000001: 0x8200,
4736         0x60000001: 0x200,
4737         0x70000001: 0x800202,
4738         0x80000001: 0x808202,
4739         0x90000001: 0x808000,
4740         0xa0000001: 0x800002,
4741         0xb0000001: 0x8202,
4742         0xc0000001: 0x202,
4743         0xd0000001: 0x800200,
4744         0xe0000001: 0x8002,
4745         0xf0000001: 0x0,
4746         0x8000001: 0x808202,
4747         0x18000001: 0x808000,
4748         0x28000001: 0x800000,
4749         0x38000001: 0x200,
4750         0x48000001: 0x8000,
4751         0x58000001: 0x800002,
4752         0x68000001: 0x2,
4753         0x78000001: 0x8202,
4754         0x88000001: 0x8002,
4755         0x98000001: 0x800202,
4756         0xa8000001: 0x202,
4757         0xb8000001: 0x808200,
4758         0xc8000001: 0x800200,
4759         0xd8000001: 0x0,
4760         0xe8000001: 0x8200,
4761         0xf8000001: 0x808002
4762       },
4763       {
4764         0x0: 0x40084010,
4765         0x1000000: 0x4000,
4766         0x2000000: 0x80000,
4767         0x3000000: 0x40080010,
4768         0x4000000: 0x40000010,
4769         0x5000000: 0x40084000,
4770         0x6000000: 0x40004000,
4771         0x7000000: 0x10,
4772         0x8000000: 0x84000,
4773         0x9000000: 0x40004010,
4774         0xa000000: 0x40000000,
4775         0xb000000: 0x84010,
4776         0xc000000: 0x80010,
4777         0xd000000: 0x0,
4778         0xe000000: 0x4010,
4779         0xf000000: 0x40080000,
4780         0x800000: 0x40004000,
4781         0x1800000: 0x84010,
4782         0x2800000: 0x10,
4783         0x3800000: 0x40004010,
4784         0x4800000: 0x40084010,
4785         0x5800000: 0x40000000,
4786         0x6800000: 0x80000,
4787         0x7800000: 0x40080010,
4788         0x8800000: 0x80010,
4789         0x9800000: 0x0,
4790         0xa800000: 0x4000,
4791         0xb800000: 0x40080000,
4792         0xc800000: 0x40000010,
4793         0xd800000: 0x84000,
4794         0xe800000: 0x40084000,
4795         0xf800000: 0x4010,
4796         0x10000000: 0x0,
4797         0x11000000: 0x40080010,
4798         0x12000000: 0x40004010,
4799         0x13000000: 0x40084000,
4800         0x14000000: 0x40080000,
4801         0x15000000: 0x10,
4802         0x16000000: 0x84010,
4803         0x17000000: 0x4000,
4804         0x18000000: 0x4010,
4805         0x19000000: 0x80000,
4806         0x1a000000: 0x80010,
4807         0x1b000000: 0x40000010,
4808         0x1c000000: 0x84000,
4809         0x1d000000: 0x40004000,
4810         0x1e000000: 0x40000000,
4811         0x1f000000: 0x40084010,
4812         0x10800000: 0x84010,
4813         0x11800000: 0x80000,
4814         0x12800000: 0x40080000,
4815         0x13800000: 0x4000,
4816         0x14800000: 0x40004000,
4817         0x15800000: 0x40084010,
4818         0x16800000: 0x10,
4819         0x17800000: 0x40000000,
4820         0x18800000: 0x40084000,
4821         0x19800000: 0x40000010,
4822         0x1a800000: 0x40004010,
4823         0x1b800000: 0x80010,
4824         0x1c800000: 0x0,
4825         0x1d800000: 0x4010,
4826         0x1e800000: 0x40080010,
4827         0x1f800000: 0x84000
4828       },
4829       {
4830         0x0: 0x104,
4831         0x100000: 0x0,
4832         0x200000: 0x4000100,
4833         0x300000: 0x10104,
4834         0x400000: 0x10004,
4835         0x500000: 0x4000004,
4836         0x600000: 0x4010104,
4837         0x700000: 0x4010000,
4838         0x800000: 0x4000000,
4839         0x900000: 0x4010100,
4840         0xa00000: 0x10100,
4841         0xb00000: 0x4010004,
4842         0xc00000: 0x4000104,
4843         0xd00000: 0x10000,
4844         0xe00000: 0x4,
4845         0xf00000: 0x100,
4846         0x80000: 0x4010100,
4847         0x180000: 0x4010004,
4848         0x280000: 0x0,
4849         0x380000: 0x4000100,
4850         0x480000: 0x4000004,
4851         0x580000: 0x10000,
4852         0x680000: 0x10004,
4853         0x780000: 0x104,
4854         0x880000: 0x4,
4855         0x980000: 0x100,
4856         0xa80000: 0x4010000,
4857         0xb80000: 0x10104,
4858         0xc80000: 0x10100,
4859         0xd80000: 0x4000104,
4860         0xe80000: 0x4010104,
4861         0xf80000: 0x4000000,
4862         0x1000000: 0x4010100,
4863         0x1100000: 0x10004,
4864         0x1200000: 0x10000,
4865         0x1300000: 0x4000100,
4866         0x1400000: 0x100,
4867         0x1500000: 0x4010104,
4868         0x1600000: 0x4000004,
4869         0x1700000: 0x0,
4870         0x1800000: 0x4000104,
4871         0x1900000: 0x4000000,
4872         0x1a00000: 0x4,
4873         0x1b00000: 0x10100,
4874         0x1c00000: 0x4010000,
4875         0x1d00000: 0x104,
4876         0x1e00000: 0x10104,
4877         0x1f00000: 0x4010004,
4878         0x1080000: 0x4000000,
4879         0x1180000: 0x104,
4880         0x1280000: 0x4010100,
4881         0x1380000: 0x0,
4882         0x1480000: 0x10004,
4883         0x1580000: 0x4000100,
4884         0x1680000: 0x100,
4885         0x1780000: 0x4010004,
4886         0x1880000: 0x10000,
4887         0x1980000: 0x4010104,
4888         0x1a80000: 0x10104,
4889         0x1b80000: 0x4000004,
4890         0x1c80000: 0x4000104,
4891         0x1d80000: 0x4010000,
4892         0x1e80000: 0x4,
4893         0x1f80000: 0x10100
4894       },
4895       {
4896         0x0: 0x80401000,
4897         0x10000: 0x80001040,
4898         0x20000: 0x401040,
4899         0x30000: 0x80400000,
4900         0x40000: 0x0,
4901         0x50000: 0x401000,
4902         0x60000: 0x80000040,
4903         0x70000: 0x400040,
4904         0x80000: 0x80000000,
4905         0x90000: 0x400000,
4906         0xa0000: 0x40,
4907         0xb0000: 0x80001000,
4908         0xc0000: 0x80400040,
4909         0xd0000: 0x1040,
4910         0xe0000: 0x1000,
4911         0xf0000: 0x80401040,
4912         0x8000: 0x80001040,
4913         0x18000: 0x40,
4914         0x28000: 0x80400040,
4915         0x38000: 0x80001000,
4916         0x48000: 0x401000,
4917         0x58000: 0x80401040,
4918         0x68000: 0x0,
4919         0x78000: 0x80400000,
4920         0x88000: 0x1000,
4921         0x98000: 0x80401000,
4922         0xa8000: 0x400000,
4923         0xb8000: 0x1040,
4924         0xc8000: 0x80000000,
4925         0xd8000: 0x400040,
4926         0xe8000: 0x401040,
4927         0xf8000: 0x80000040,
4928         0x100000: 0x400040,
4929         0x110000: 0x401000,
4930         0x120000: 0x80000040,
4931         0x130000: 0x0,
4932         0x140000: 0x1040,
4933         0x150000: 0x80400040,
4934         0x160000: 0x80401000,
4935         0x170000: 0x80001040,
4936         0x180000: 0x80401040,
4937         0x190000: 0x80000000,
4938         0x1a0000: 0x80400000,
4939         0x1b0000: 0x401040,
4940         0x1c0000: 0x80001000,
4941         0x1d0000: 0x400000,
4942         0x1e0000: 0x40,
4943         0x1f0000: 0x1000,
4944         0x108000: 0x80400000,
4945         0x118000: 0x80401040,
4946         0x128000: 0x0,
4947         0x138000: 0x401000,
4948         0x148000: 0x400040,
4949         0x158000: 0x80000000,
4950         0x168000: 0x80001040,
4951         0x178000: 0x40,
4952         0x188000: 0x80000040,
4953         0x198000: 0x1000,
4954         0x1a8000: 0x80001000,
4955         0x1b8000: 0x80400040,
4956         0x1c8000: 0x1040,
4957         0x1d8000: 0x80401000,
4958         0x1e8000: 0x400000,
4959         0x1f8000: 0x401040
4960       },
4961       {
4962         0x0: 0x80,
4963         0x1000: 0x1040000,
4964         0x2000: 0x40000,
4965         0x3000: 0x20000000,
4966         0x4000: 0x20040080,
4967         0x5000: 0x1000080,
4968         0x6000: 0x21000080,
4969         0x7000: 0x40080,
4970         0x8000: 0x1000000,
4971         0x9000: 0x20040000,
4972         0xa000: 0x20000080,
4973         0xb000: 0x21040080,
4974         0xc000: 0x21040000,
4975         0xd000: 0x0,
4976         0xe000: 0x1040080,
4977         0xf000: 0x21000000,
4978         0x800: 0x1040080,
4979         0x1800: 0x21000080,
4980         0x2800: 0x80,
4981         0x3800: 0x1040000,
4982         0x4800: 0x40000,
4983         0x5800: 0x20040080,
4984         0x6800: 0x21040000,
4985         0x7800: 0x20000000,
4986         0x8800: 0x20040000,
4987         0x9800: 0x0,
4988         0xa800: 0x21040080,
4989         0xb800: 0x1000080,
4990         0xc800: 0x20000080,
4991         0xd800: 0x21000000,
4992         0xe800: 0x1000000,
4993         0xf800: 0x40080,
4994         0x10000: 0x40000,
4995         0x11000: 0x80,
4996         0x12000: 0x20000000,
4997         0x13000: 0x21000080,
4998         0x14000: 0x1000080,
4999         0x15000: 0x21040000,
5000         0x16000: 0x20040080,
5001         0x17000: 0x1000000,
5002         0x18000: 0x21040080,
5003         0x19000: 0x21000000,
5004         0x1a000: 0x1040000,
5005         0x1b000: 0x20040000,
5006         0x1c000: 0x40080,
5007         0x1d000: 0x20000080,
5008         0x1e000: 0x0,
5009         0x1f000: 0x1040080,
5010         0x10800: 0x21000080,
5011         0x11800: 0x1000000,
5012         0x12800: 0x1040000,
5013         0x13800: 0x20040080,
5014         0x14800: 0x20000000,
5015         0x15800: 0x1040080,
5016         0x16800: 0x80,
5017         0x17800: 0x21040000,
5018         0x18800: 0x40080,
5019         0x19800: 0x21040080,
5020         0x1a800: 0x0,
5021         0x1b800: 0x21000000,
5022         0x1c800: 0x1000080,
5023         0x1d800: 0x40000,
5024         0x1e800: 0x20040000,
5025         0x1f800: 0x20000080
5026       },
5027       {
5028         0x0: 0x10000008,
5029         0x100: 0x2000,
5030         0x200: 0x10200000,
5031         0x300: 0x10202008,
5032         0x400: 0x10002000,
5033         0x500: 0x200000,
5034         0x600: 0x200008,
5035         0x700: 0x10000000,
5036         0x800: 0x0,
5037         0x900: 0x10002008,
5038         0xa00: 0x202000,
5039         0xb00: 0x8,
5040         0xc00: 0x10200008,
5041         0xd00: 0x202008,
5042         0xe00: 0x2008,
5043         0xf00: 0x10202000,
5044         0x80: 0x10200000,
5045         0x180: 0x10202008,
5046         0x280: 0x8,
5047         0x380: 0x200000,
5048         0x480: 0x202008,
5049         0x580: 0x10000008,
5050         0x680: 0x10002000,
5051         0x780: 0x2008,
5052         0x880: 0x200008,
5053         0x980: 0x2000,
5054         0xa80: 0x10002008,
5055         0xb80: 0x10200008,
5056         0xc80: 0x0,
5057         0xd80: 0x10202000,
5058         0xe80: 0x202000,
5059         0xf80: 0x10000000,
5060         0x1000: 0x10002000,
5061         0x1100: 0x10200008,
5062         0x1200: 0x10202008,
5063         0x1300: 0x2008,
5064         0x1400: 0x200000,
5065         0x1500: 0x10000000,
5066         0x1600: 0x10000008,
5067         0x1700: 0x202000,
5068         0x1800: 0x202008,
5069         0x1900: 0x0,
5070         0x1a00: 0x8,
5071         0x1b00: 0x10200000,
5072         0x1c00: 0x2000,
5073         0x1d00: 0x10002008,
5074         0x1e00: 0x10202000,
5075         0x1f00: 0x200008,
5076         0x1080: 0x8,
5077         0x1180: 0x202000,
5078         0x1280: 0x200000,
5079         0x1380: 0x10000008,
5080         0x1480: 0x10002000,
5081         0x1580: 0x2008,
5082         0x1680: 0x10202008,
5083         0x1780: 0x10200000,
5084         0x1880: 0x10202000,
5085         0x1980: 0x10200008,
5086         0x1a80: 0x2000,
5087         0x1b80: 0x202008,
5088         0x1c80: 0x200008,
5089         0x1d80: 0x0,
5090         0x1e80: 0x10000000,
5091         0x1f80: 0x10002008
5092       },
5093       {
5094         0x0: 0x100000,
5095         0x10: 0x2000401,
5096         0x20: 0x400,
5097         0x30: 0x100401,
5098         0x40: 0x2100401,
5099         0x50: 0x0,
5100         0x60: 0x1,
5101         0x70: 0x2100001,
5102         0x80: 0x2000400,
5103         0x90: 0x100001,
5104         0xa0: 0x2000001,
5105         0xb0: 0x2100400,
5106         0xc0: 0x2100000,
5107         0xd0: 0x401,
5108         0xe0: 0x100400,
5109         0xf0: 0x2000000,
5110         0x8: 0x2100001,
5111         0x18: 0x0,
5112         0x28: 0x2000401,
5113         0x38: 0x2100400,
5114         0x48: 0x100000,
5115         0x58: 0x2000001,
5116         0x68: 0x2000000,
5117         0x78: 0x401,
5118         0x88: 0x100401,
5119         0x98: 0x2000400,
5120         0xa8: 0x2100000,
5121         0xb8: 0x100001,
5122         0xc8: 0x400,
5123         0xd8: 0x2100401,
5124         0xe8: 0x1,
5125         0xf8: 0x100400,
5126         0x100: 0x2000000,
5127         0x110: 0x100000,
5128         0x120: 0x2000401,
5129         0x130: 0x2100001,
5130         0x140: 0x100001,
5131         0x150: 0x2000400,
5132         0x160: 0x2100400,
5133         0x170: 0x100401,
5134         0x180: 0x401,
5135         0x190: 0x2100401,
5136         0x1a0: 0x100400,
5137         0x1b0: 0x1,
5138         0x1c0: 0x0,
5139         0x1d0: 0x2100000,
5140         0x1e0: 0x2000001,
5141         0x1f0: 0x400,
5142         0x108: 0x100400,
5143         0x118: 0x2000401,
5144         0x128: 0x2100001,
5145         0x138: 0x1,
5146         0x148: 0x2000000,
5147         0x158: 0x100000,
5148         0x168: 0x401,
5149         0x178: 0x2100400,
5150         0x188: 0x2000001,
5151         0x198: 0x2100000,
5152         0x1a8: 0x0,
5153         0x1b8: 0x2100401,
5154         0x1c8: 0x100401,
5155         0x1d8: 0x400,
5156         0x1e8: 0x2000400,
5157         0x1f8: 0x100001
5158       },
5159       {
5160         0x0: 0x8000820,
5161         0x1: 0x20000,
5162         0x2: 0x8000000,
5163         0x3: 0x20,
5164         0x4: 0x20020,
5165         0x5: 0x8020820,
5166         0x6: 0x8020800,
5167         0x7: 0x800,
5168         0x8: 0x8020000,
5169         0x9: 0x8000800,
5170         0xa: 0x20800,
5171         0xb: 0x8020020,
5172         0xc: 0x820,
5173         0xd: 0x0,
5174         0xe: 0x8000020,
5175         0xf: 0x20820,
5176         0x80000000: 0x800,
5177         0x80000001: 0x8020820,
5178         0x80000002: 0x8000820,
5179         0x80000003: 0x8000000,
5180         0x80000004: 0x8020000,
5181         0x80000005: 0x20800,
5182         0x80000006: 0x20820,
5183         0x80000007: 0x20,
5184         0x80000008: 0x8000020,
5185         0x80000009: 0x820,
5186         0x8000000a: 0x20020,
5187         0x8000000b: 0x8020800,
5188         0x8000000c: 0x0,
5189         0x8000000d: 0x8020020,
5190         0x8000000e: 0x8000800,
5191         0x8000000f: 0x20000,
5192         0x10: 0x20820,
5193         0x11: 0x8020800,
5194         0x12: 0x20,
5195         0x13: 0x800,
5196         0x14: 0x8000800,
5197         0x15: 0x8000020,
5198         0x16: 0x8020020,
5199         0x17: 0x20000,
5200         0x18: 0x0,
5201         0x19: 0x20020,
5202         0x1a: 0x8020000,
5203         0x1b: 0x8000820,
5204         0x1c: 0x8020820,
5205         0x1d: 0x20800,
5206         0x1e: 0x820,
5207         0x1f: 0x8000000,
5208         0x80000010: 0x20000,
5209         0x80000011: 0x800,
5210         0x80000012: 0x8020020,
5211         0x80000013: 0x20820,
5212         0x80000014: 0x20,
5213         0x80000015: 0x8020000,
5214         0x80000016: 0x8000000,
5215         0x80000017: 0x8000820,
5216         0x80000018: 0x8020820,
5217         0x80000019: 0x8000020,
5218         0x8000001a: 0x8000800,
5219         0x8000001b: 0x0,
5220         0x8000001c: 0x20800,
5221         0x8000001d: 0x820,
5222         0x8000001e: 0x20020,
5223         0x8000001f: 0x8020800
5224       }
5225     ];
5226 
5227     // Masks that select the SBOX input
5228     var SBOX_MASK = [
5229       0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000,
5230       0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f
5231     ];
5232 
5233     /**
5234      * DES block cipher algorithm.
5235      */
5236     var DES = C_algo.DES = BlockCipher.extend({
5237       _doReset: function() {
5238         // Shortcuts
5239         var key = this._key;
5240         var keyWords = key.words;
5241 
5242         // Select 56 bits according to PC1
5243         var keyBits = [];
5244         for (var i = 0; i < 56; i++) {
5245           var keyBitPos = PC1[i] - 1;
5246           keyBits[i] = (keyWords[keyBitPos >>> 5] >>> (31 - keyBitPos % 32)) & 1;
5247         }
5248 
5249         // Assemble 16 subkeys
5250         var subKeys = this._subKeys = [];
5251         for (var nSubKey = 0; nSubKey < 16; nSubKey++) {
5252           // Create subkey
5253           var subKey = subKeys[nSubKey] = [];
5254 
5255           // Shortcut
5256           var bitShift = BIT_SHIFTS[nSubKey];
5257 
5258           // Select 48 bits according to PC2
5259           for (var i = 0; i < 24; i++) {
5260             // Select from the left 28 key bits
5261             subKey[(i / 6) | 0] |= keyBits[((PC2[i] - 1) + bitShift) % 28] << (31 - i % 6);
5262 
5263             // Select from the right 28 key bits
5264             subKey[4 + ((i / 6) | 0)] |= keyBits[28 + (((PC2[i + 24] - 1) + bitShift) % 28)] << (31 - i % 6);
5265           }
5266 
5267           // Since each subkey is applied to an expanded 32-bit input,
5268           // the subkey can be broken into 8 values scaled to 32-bits,
5269           // which allows the key to be used without expansion
5270           subKey[0] = (subKey[0] << 1) | (subKey[0] >>> 31);
5271           for (var i = 1; i < 7; i++) {
5272             subKey[i] = subKey[i] >>> ((i - 1) * 4 + 3);
5273           }
5274           subKey[7] = (subKey[7] << 5) | (subKey[7] >>> 27);
5275         }
5276 
5277         // Compute inverse subkeys
5278         var invSubKeys = this._invSubKeys = [];
5279         for (var i = 0; i < 16; i++) {
5280           invSubKeys[i] = subKeys[15 - i];
5281         }
5282       },
5283 
5284       encryptBlock: function(M, offset) {
5285         this._doCryptBlock(M, offset, this._subKeys);
5286       },
5287 
5288       decryptBlock: function(M, offset) {
5289         this._doCryptBlock(M, offset, this._invSubKeys);
5290       },
5291 
5292       _doCryptBlock: function(M, offset, subKeys) {
5293         // Get input
5294         this._lBlock = M[offset];
5295         this._rBlock = M[offset + 1];
5296 
5297         // Initial permutation
5298         exchangeLR.call(this, 4, 0x0f0f0f0f);
5299         exchangeLR.call(this, 16, 0x0000ffff);
5300         exchangeRL.call(this, 2, 0x33333333);
5301         exchangeRL.call(this, 8, 0x00ff00ff);
5302         exchangeLR.call(this, 1, 0x55555555);
5303 
5304         // Rounds
5305         for (var round = 0; round < 16; round++) {
5306           // Shortcuts
5307           var subKey = subKeys[round];
5308           var lBlock = this._lBlock;
5309           var rBlock = this._rBlock;
5310 
5311           // Feistel function
5312           var f = 0;
5313           for (var i = 0; i < 8; i++) {
5314             f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0];
5315           }
5316           this._lBlock = rBlock;
5317           this._rBlock = lBlock ^ f;
5318         }
5319 
5320         // Undo swap from last round
5321         var t = this._lBlock;
5322         this._lBlock = this._rBlock;
5323         this._rBlock = t;
5324 
5325         // Final permutation
5326         exchangeLR.call(this, 1, 0x55555555);
5327         exchangeRL.call(this, 8, 0x00ff00ff);
5328         exchangeRL.call(this, 2, 0x33333333);
5329         exchangeLR.call(this, 16, 0x0000ffff);
5330         exchangeLR.call(this, 4, 0x0f0f0f0f);
5331 
5332         // Set output
5333         M[offset] = this._lBlock;
5334         M[offset + 1] = this._rBlock;
5335       },
5336 
5337       keySize: 64 / 32,
5338 
5339       ivSize: 64 / 32,
5340 
5341       blockSize: 64 / 32
5342     });
5343 
5344     // Swap bits across the left and right words
5345     function exchangeLR(offset, mask) {
5346       var t = ((this._lBlock >>> offset) ^ this._rBlock) & mask;
5347       this._rBlock ^= t;
5348       this._lBlock ^= t << offset;
5349     }
5350 
5351     function exchangeRL(offset, mask) {
5352       var t = ((this._rBlock >>> offset) ^ this._lBlock) & mask;
5353       this._lBlock ^= t;
5354       this._rBlock ^= t << offset;
5355     }
5356 
5357     /**
5358      * Shortcut functions to the cipher's object interface.
5359      *
5360      * @example
5361      *
5362      *     var ciphertext = CryptoJS.DES.encrypt(message, key, cfg);
5363      *     var plaintext  = CryptoJS.DES.decrypt(ciphertext, key, cfg);
5364      */
5365     C.DES = BlockCipher._createHelper(DES);
5366 
5367     /**
5368      * Triple-DES block cipher algorithm.
5369      */
5370     var TripleDES = C_algo.TripleDES = BlockCipher.extend({
5371       _doReset: function() {
5372         // Shortcuts
5373         var key = this._key;
5374         var keyWords = key.words;
5375         // Make sure the key length is valid (64, 128 or >= 192 bit)
5376         if (keyWords.length !== 2 && keyWords.length !== 4 && keyWords.length < 6) {
5377           throw new Error('Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192.');
5378         }
5379 
5380         // Extend the key according to the keying options defined in 3DES standard
5381         var key1 = keyWords.slice(0, 2);
5382         var key2 = keyWords.length < 4 ? keyWords.slice(0, 2) : keyWords.slice(2, 4);
5383         var key3 = keyWords.length < 6 ? keyWords.slice(0, 2) : keyWords.slice(4, 6);
5384 
5385         // Create DES instances
5386         this._des1 = DES.createEncryptor(WordArray.create(key1));
5387         this._des2 = DES.createEncryptor(WordArray.create(key2));
5388         this._des3 = DES.createEncryptor(WordArray.create(key3));
5389       },
5390 
5391       encryptBlock: function(M, offset) {
5392         this._des1.encryptBlock(M, offset);
5393         this._des2.decryptBlock(M, offset);
5394         this._des3.encryptBlock(M, offset);
5395       },
5396 
5397       decryptBlock: function(M, offset) {
5398         this._des3.decryptBlock(M, offset);
5399         this._des2.encryptBlock(M, offset);
5400         this._des1.decryptBlock(M, offset);
5401       },
5402 
5403       keySize: 192 / 32,
5404 
5405       ivSize: 64 / 32,
5406 
5407       blockSize: 64 / 32
5408     });
5409 
5410     /**
5411      * Shortcut functions to the cipher's object interface.
5412      *
5413      * @example
5414      *
5415      *     var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg);
5416      *     var plaintext  = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg);
5417      */
5418     C.TripleDES = BlockCipher._createHelper(TripleDES);
5419   }());
5420 
5421 
5422   (function() {
5423     // Shortcuts
5424     var C = CryptoJS;
5425     var C_lib = C.lib;
5426     var StreamCipher = C_lib.StreamCipher;
5427     var C_algo = C.algo;
5428 
5429     /**
5430      * RC4 stream cipher algorithm.
5431      */
5432     var RC4 = C_algo.RC4 = StreamCipher.extend({
5433       _doReset: function() {
5434         // Shortcuts
5435         var key = this._key;
5436         var keyWords = key.words;
5437         var keySigBytes = key.sigBytes;
5438 
5439         // Init sbox
5440         var S = this._S = [];
5441         for (var i = 0; i < 256; i++) {
5442           S[i] = i;
5443         }
5444 
5445         // Key setup
5446         for (var i = 0, j = 0; i < 256; i++) {
5447           var keyByteIndex = i % keySigBytes;
5448           var keyByte = (keyWords[keyByteIndex >>> 2] >>> (24 - (keyByteIndex % 4) * 8)) & 0xff;
5449 
5450           j = (j + S[i] + keyByte) % 256;
5451 
5452           // Swap
5453           var t = S[i];
5454           S[i] = S[j];
5455           S[j] = t;
5456         }
5457 
5458         // Counters
5459         this._i = this._j = 0;
5460       },
5461 
5462       _doProcessBlock: function(M, offset) {
5463         M[offset] ^= generateKeystreamWord.call(this);
5464       },
5465 
5466       keySize: 256 / 32,
5467 
5468       ivSize: 0
5469     });
5470 
5471     function generateKeystreamWord() {
5472       // Shortcuts
5473       var S = this._S;
5474       var i = this._i;
5475       var j = this._j;
5476 
5477       // Generate keystream word
5478       var keystreamWord = 0;
5479       for (var n = 0; n < 4; n++) {
5480         i = (i + 1) % 256;
5481         j = (j + S[i]) % 256;
5482 
5483         // Swap
5484         var t = S[i];
5485         S[i] = S[j];
5486         S[j] = t;
5487 
5488         keystreamWord |= S[(S[i] + S[j]) % 256] << (24 - n * 8);
5489       }
5490 
5491       // Update counters
5492       this._i = i;
5493       this._j = j;
5494 
5495       return keystreamWord;
5496     }
5497 
5498     /**
5499      * Shortcut functions to the cipher's object interface.
5500      *
5501      * @example
5502      *
5503      *     var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg);
5504      *     var plaintext  = CryptoJS.RC4.decrypt(ciphertext, key, cfg);
5505      */
5506     C.RC4 = StreamCipher._createHelper(RC4);
5507 
5508     /**
5509      * Modified RC4 stream cipher algorithm.
5510      */
5511     var RC4Drop = C_algo.RC4Drop = RC4.extend({
5512       /**
5513        * Configuration options.
5514        *
5515        * @property {number} drop The number of keystream words to drop. Default 192
5516        */
5517       cfg: RC4.cfg.extend({
5518         drop: 192
5519       }),
5520 
5521       _doReset: function() {
5522         RC4._doReset.call(this);
5523 
5524         // Drop
5525         for (var i = this.cfg.drop; i > 0; i--) {
5526           generateKeystreamWord.call(this);
5527         }
5528       }
5529     });
5530 
5531     /**
5532      * Shortcut functions to the cipher's object interface.
5533      *
5534      * @example
5535      *
5536      *     var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg);
5537      *     var plaintext  = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg);
5538      */
5539     C.RC4Drop = StreamCipher._createHelper(RC4Drop);
5540   }());
5541 
5542 
5543   /** @preserve
5544    * Counter block mode compatible with  Dr Brian Gladman fileenc.c
5545    * derived from CryptoJS.mode.CTR
5546    * Jan Hruby jhruby.web@gmail.com
5547    */
5548   CryptoJS.mode.CTRGladman = (function() {
5549     var CTRGladman = CryptoJS.lib.BlockCipherMode.extend();
5550 
5551     function incWord(word) {
5552       if (((word >> 24) & 0xff) === 0xff) { //overflow
5553         var b1 = (word >> 16) & 0xff;
5554         var b2 = (word >> 8) & 0xff;
5555         var b3 = word & 0xff;
5556 
5557         if (b1 === 0xff) // overflow b1
5558         {
5559           b1 = 0;
5560           if (b2 === 0xff) {
5561             b2 = 0;
5562             if (b3 === 0xff) {
5563               b3 = 0;
5564             } else {
5565               ++b3;
5566             }
5567           } else {
5568             ++b2;
5569           }
5570         } else {
5571           ++b1;
5572         }
5573 
5574         word = 0;
5575         word += (b1 << 16);
5576         word += (b2 << 8);
5577         word += b3;
5578       } else {
5579         word += (0x01 << 24);
5580       }
5581       return word;
5582     }
5583 
5584     function incCounter(counter) {
5585       if ((counter[0] = incWord(counter[0])) === 0) {
5586         // encr_data in fileenc.c from  Dr Brian Gladman's counts only with DWORD j < 8
5587         counter[1] = incWord(counter[1]);
5588       }
5589       return counter;
5590     }
5591 
5592     var Encryptor = CTRGladman.Encryptor = CTRGladman.extend({
5593       processBlock: function(words, offset) {
5594         // Shortcuts
5595         var cipher = this._cipher
5596         var blockSize = cipher.blockSize;
5597         var iv = this._iv;
5598         var counter = this._counter;
5599 
5600         // Generate keystream
5601         if (iv) {
5602           counter = this._counter = iv.slice(0);
5603 
5604           // Remove IV for subsequent blocks
5605           this._iv = undefined;
5606         }
5607 
5608         incCounter(counter);
5609 
5610         var keystream = counter.slice(0);
5611         cipher.encryptBlock(keystream, 0);
5612 
5613         // Encrypt
5614         for (var i = 0; i < blockSize; i++) {
5615           words[offset + i] ^= keystream[i];
5616         }
5617       }
5618     });
5619 
5620     CTRGladman.Decryptor = Encryptor;
5621 
5622     return CTRGladman;
5623   }());
5624 
5625 
5626 
5627 
5628   (function() {
5629     // Shortcuts
5630     var C = CryptoJS;
5631     var C_lib = C.lib;
5632     var StreamCipher = C_lib.StreamCipher;
5633     var C_algo = C.algo;
5634 
5635     // Reusable objects
5636     var S = [];
5637     var C_ = [];
5638     var G = [];
5639 
5640     /**
5641      * Rabbit stream cipher algorithm
5642      */
5643     var Rabbit = C_algo.Rabbit = StreamCipher.extend({
5644       _doReset: function() {
5645         // Shortcuts
5646         var K = this._key.words;
5647         var iv = this.cfg.iv;
5648 
5649         // Swap endian
5650         for (var i = 0; i < 4; i++) {
5651           K[i] = (((K[i] << 8) | (K[i] >>> 24)) & 0x00ff00ff) |
5652             (((K[i] << 24) | (K[i] >>> 8)) & 0xff00ff00);
5653         }
5654 
5655         // Generate initial state values
5656         var X = this._X = [
5657           K[0], (K[3] << 16) | (K[2] >>> 16),
5658           K[1], (K[0] << 16) | (K[3] >>> 16),
5659           K[2], (K[1] << 16) | (K[0] >>> 16),
5660           K[3], (K[2] << 16) | (K[1] >>> 16)
5661         ];
5662 
5663         // Generate initial counter values
5664         var C = this._C = [
5665           (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff),
5666           (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff),
5667           (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff),
5668           (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff)
5669         ];
5670 
5671         // Carry bit
5672         this._b = 0;
5673 
5674         // Iterate the system four times
5675         for (var i = 0; i < 4; i++) {
5676           nextState.call(this);
5677         }
5678 
5679         // Modify the counters
5680         for (var i = 0; i < 8; i++) {
5681           C[i] ^= X[(i + 4) & 7];
5682         }
5683 
5684         // IV setup
5685         if (iv) {
5686           // Shortcuts
5687           var IV = iv.words;
5688           var IV_0 = IV[0];
5689           var IV_1 = IV[1];
5690 
5691           // Generate four subvectors
5692           var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00);
5693           var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00);
5694           var i1 = (i0 >>> 16) | (i2 & 0xffff0000);
5695           var i3 = (i2 << 16) | (i0 & 0x0000ffff);
5696 
5697           // Modify counter values
5698           C[0] ^= i0;
5699           C[1] ^= i1;
5700           C[2] ^= i2;
5701           C[3] ^= i3;
5702           C[4] ^= i0;
5703           C[5] ^= i1;
5704           C[6] ^= i2;
5705           C[7] ^= i3;
5706 
5707           // Iterate the system four times
5708           for (var i = 0; i < 4; i++) {
5709             nextState.call(this);
5710           }
5711         }
5712       },
5713 
5714       _doProcessBlock: function(M, offset) {
5715         // Shortcut
5716         var X = this._X;
5717 
5718         // Iterate the system
5719         nextState.call(this);
5720 
5721         // Generate four keystream words
5722         S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16);
5723         S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16);
5724         S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16);
5725         S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16);
5726 
5727         for (var i = 0; i < 4; i++) {
5728           // Swap endian
5729           S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) |
5730             (((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00);
5731 
5732           // Encrypt
5733           M[offset + i] ^= S[i];
5734         }
5735       },
5736 
5737       blockSize: 128 / 32,
5738 
5739       ivSize: 64 / 32
5740     });
5741 
5742     function nextState() {
5743       // Shortcuts
5744       var X = this._X;
5745       var C = this._C;
5746 
5747       // Save old counter values
5748       for (var i = 0; i < 8; i++) {
5749         C_[i] = C[i];
5750       }
5751 
5752       // Calculate new counter values
5753       C[0] = (C[0] + 0x4d34d34d + this._b) | 0;
5754       C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0;
5755       C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0;
5756       C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0;
5757       C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0;
5758       C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0;
5759       C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0;
5760       C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0;
5761       this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0;
5762 
5763       // Calculate the g-values
5764       for (var i = 0; i < 8; i++) {
5765         var gx = X[i] + C[i];
5766 
5767         // Construct high and low argument for squaring
5768         var ga = gx & 0xffff;
5769         var gb = gx >>> 16;
5770 
5771         // Calculate high and low result of squaring
5772         var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb;
5773         var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0);
5774 
5775         // High XOR low
5776         G[i] = gh ^ gl;
5777       }
5778 
5779       // Calculate new state values
5780       X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0;
5781       X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0;
5782       X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0;
5783       X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0;
5784       X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0;
5785       X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0;
5786       X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0;
5787       X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0;
5788     }
5789 
5790     /**
5791      * Shortcut functions to the cipher's object interface.
5792      *
5793      * @example
5794      *
5795      *     var ciphertext = CryptoJS.Rabbit.encrypt(message, key, cfg);
5796      *     var plaintext  = CryptoJS.Rabbit.decrypt(ciphertext, key, cfg);
5797      */
5798     C.Rabbit = StreamCipher._createHelper(Rabbit);
5799   }());
5800 
5801 
5802   /**
5803    * Counter block mode.
5804    */
5805   CryptoJS.mode.CTR = (function() {
5806     var CTR = CryptoJS.lib.BlockCipherMode.extend();
5807 
5808     var Encryptor = CTR.Encryptor = CTR.extend({
5809       processBlock: function(words, offset) {
5810         // Shortcuts
5811         var cipher = this._cipher
5812         var blockSize = cipher.blockSize;
5813         var iv = this._iv;
5814         var counter = this._counter;
5815 
5816         // Generate keystream
5817         if (iv) {
5818           counter = this._counter = iv.slice(0);
5819 
5820           // Remove IV for subsequent blocks
5821           this._iv = undefined;
5822         }
5823         var keystream = counter.slice(0);
5824         cipher.encryptBlock(keystream, 0);
5825 
5826         // Increment counter
5827         counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0
5828 
5829         // Encrypt
5830         for (var i = 0; i < blockSize; i++) {
5831           words[offset + i] ^= keystream[i];
5832         }
5833       }
5834     });
5835 
5836     CTR.Decryptor = Encryptor;
5837 
5838     return CTR;
5839   }());
5840 
5841 
5842   (function() {
5843     // Shortcuts
5844     var C = CryptoJS;
5845     var C_lib = C.lib;
5846     var StreamCipher = C_lib.StreamCipher;
5847     var C_algo = C.algo;
5848 
5849     // Reusable objects
5850     var S = [];
5851     var C_ = [];
5852     var G = [];
5853 
5854     /**
5855      * Rabbit stream cipher algorithm.
5856      *
5857      * This is a legacy version that neglected to convert the key to little-endian.
5858      * This error doesn't affect the cipher's security,
5859      * but it does affect its compatibility with other implementations.
5860      */
5861     var RabbitLegacy = C_algo.RabbitLegacy = StreamCipher.extend({
5862       _doReset: function() {
5863         // Shortcuts
5864         var K = this._key.words;
5865         var iv = this.cfg.iv;
5866 
5867         // Generate initial state values
5868         var X = this._X = [
5869           K[0], (K[3] << 16) | (K[2] >>> 16),
5870           K[1], (K[0] << 16) | (K[3] >>> 16),
5871           K[2], (K[1] << 16) | (K[0] >>> 16),
5872           K[3], (K[2] << 16) | (K[1] >>> 16)
5873         ];
5874 
5875         // Generate initial counter values
5876         var C = this._C = [
5877           (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff),
5878           (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff),
5879           (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff),
5880           (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff)
5881         ];
5882 
5883         // Carry bit
5884         this._b = 0;
5885 
5886         // Iterate the system four times
5887         for (var i = 0; i < 4; i++) {
5888           nextState.call(this);
5889         }
5890 
5891         // Modify the counters
5892         for (var i = 0; i < 8; i++) {
5893           C[i] ^= X[(i + 4) & 7];
5894         }
5895 
5896         // IV setup
5897         if (iv) {
5898           // Shortcuts
5899           var IV = iv.words;
5900           var IV_0 = IV[0];
5901           var IV_1 = IV[1];
5902 
5903           // Generate four subvectors
5904           var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00);
5905           var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00);
5906           var i1 = (i0 >>> 16) | (i2 & 0xffff0000);
5907           var i3 = (i2 << 16) | (i0 & 0x0000ffff);
5908 
5909           // Modify counter values
5910           C[0] ^= i0;
5911           C[1] ^= i1;
5912           C[2] ^= i2;
5913           C[3] ^= i3;
5914           C[4] ^= i0;
5915           C[5] ^= i1;
5916           C[6] ^= i2;
5917           C[7] ^= i3;
5918 
5919           // Iterate the system four times
5920           for (var i = 0; i < 4; i++) {
5921             nextState.call(this);
5922           }
5923         }
5924       },
5925 
5926       _doProcessBlock: function(M, offset) {
5927         // Shortcut
5928         var X = this._X;
5929 
5930         // Iterate the system
5931         nextState.call(this);
5932 
5933         // Generate four keystream words
5934         S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16);
5935         S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16);
5936         S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16);
5937         S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16);
5938 
5939         for (var i = 0; i < 4; i++) {
5940           // Swap endian
5941           S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) |
5942             (((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00);
5943 
5944           // Encrypt
5945           M[offset + i] ^= S[i];
5946         }
5947       },
5948 
5949       blockSize: 128 / 32,
5950 
5951       ivSize: 64 / 32
5952     });
5953 
5954     function nextState() {
5955       // Shortcuts
5956       var X = this._X;
5957       var C = this._C;
5958 
5959       // Save old counter values
5960       for (var i = 0; i < 8; i++) {
5961         C_[i] = C[i];
5962       }
5963 
5964       // Calculate new counter values
5965       C[0] = (C[0] + 0x4d34d34d + this._b) | 0;
5966       C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0;
5967       C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0;
5968       C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0;
5969       C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0;
5970       C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0;
5971       C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0;
5972       C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0;
5973       this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0;
5974 
5975       // Calculate the g-values
5976       for (var i = 0; i < 8; i++) {
5977         var gx = X[i] + C[i];
5978 
5979         // Construct high and low argument for squaring
5980         var ga = gx & 0xffff;
5981         var gb = gx >>> 16;
5982 
5983         // Calculate high and low result of squaring
5984         var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb;
5985         var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0);
5986 
5987         // High XOR low
5988         G[i] = gh ^ gl;
5989       }
5990 
5991       // Calculate new state values
5992       X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0;
5993       X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0;
5994       X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0;
5995       X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0;
5996       X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0;
5997       X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0;
5998       X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0;
5999       X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0;
6000     }
6001 
6002     /**
6003      * Shortcut functions to the cipher's object interface.
6004      *
6005      * @example
6006      *
6007      *     var ciphertext = CryptoJS.RabbitLegacy.encrypt(message, key, cfg);
6008      *     var plaintext  = CryptoJS.RabbitLegacy.decrypt(ciphertext, key, cfg);
6009      */
6010     C.RabbitLegacy = StreamCipher._createHelper(RabbitLegacy);
6011   }());
6012 
6013 
6014   /**
6015    * Zero padding strategy.
6016    */
6017   CryptoJS.pad.ZeroPadding = {
6018     pad: function(data, blockSize) {
6019       // Shortcut
6020       var blockSizeBytes = blockSize * 4;
6021 
6022       // Pad
6023       data.clamp();
6024       data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);
6025     },
6026 
6027     unpad: function(data) {
6028       // Shortcut
6029       var dataWords = data.words;
6030 
6031       // Unpad
6032       var i = data.sigBytes - 1;
6033       for (var i = data.sigBytes - 1; i >= 0; i--) {
6034         if (((dataWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff)) {
6035           data.sigBytes = i + 1;
6036           break;
6037         }
6038       }
6039     }
6040   };
6041 module.exports = CryptoJS

  (注意:最后一行代碼!!!必須有!!!)

第二步:在一個新的Js文件內  封裝加密和解密方法 ;

 1 var CryptoJS = require('../crypto-js.js');  //引入aes源碼
 2 var key = CryptoJS.enc.Utf8.parse('0123456789abcdef'); //十六位十六進制數作為秘鑰 (后端提供)
 3 /**
 4  * 加密 (ECB 模式)
 5  */
 6 function Encrypt(word) {
 7     var srcs = CryptoJS.enc.Utf8.parse(word);
 8     var encrypted = CryptoJS.AES.encrypt(srcs, key, {
 9         mode: CryptoJS.mode.ECB,
10         padding: CryptoJS.pad.Pkcs7
11     });
12     // return encrypted.toString(); 
13     return encrypted.ciphertext.toString().toUpperCase();//這里需要注意,return出去的格式,可能導致后端無法解密,可能是上面 return 出去的結果
14 }
15 /**
16  * 解密
17  */
18 function Decrypt(word) {
19     var decrypt = CryptoJS.AES.decrypt(word, key, {
20         mode: CryptoJS.mode.ECB,
21         padding: CryptoJS.pad.Pkcs7
22     });
23     return CryptoJS.enc.Utf8.stringify(decrypt).toString();
24 }
25 
26 //暴露接口
27 module.exports.Decrypt = Decrypt;
28 module.exports.Encrypt = Encrypt;

第三步:在你需要加密的 js 文件內 引入封裝好的加密解密方法 

1 const CryptoJS = require('../../utils/aes.js'); //aes加密
2 // aes加密
3 appEnCryption() {
4     var str = "abcdefghigklmnopqrstuvwxyz"
5     var encryStr = CryptoJS.Encrypt(str)
6     console.log("加密", CryptoJS.Encrypt(str))
7     console.log("解密",CryptoJS.Decrypt(encryStr))
8     return encryStr
9   },

 

  2.CBC模式(需要初始向量iv 、AES加密用的key)

    第一步:在一個公共文件夾引入下面aes源碼;可以直接復制下面的代碼

/**
 * [description] CryptoJS v3.1.2 
 * [description] zhuangzhudada sort out 
 */
var CryptoJS = CryptoJS || function(u, p) {
    var d = {},
        l = d.lib = {},
        s = function() {},
        t = l.Base = {
            extend: function(a) {
                s.prototype = this;
                var c = new s;
                a && c.mixIn(a);
                c.hasOwnProperty("init") || (c.init = function() {
                    c.$super.init.apply(this, arguments)
                });
                c.init.prototype = c;
                c.$super = this;
                return c
            },
            create: function() {
                var a = this.extend();
                a.init.apply(a, arguments);
                return a
            },
            init: function() {},
            mixIn: function(a) {
                for (var c in a) a.hasOwnProperty(c) && (this[c] = a[c]);
                a.hasOwnProperty("toString") && (this.toString = a.toString)
            },
            clone: function() {
                return this.init.prototype.extend(this)
            }
        },
        r = l.WordArray = t.extend({
            init: function(a, c) {
                a = this.words = a || [];
                this.sigBytes = c != p ? c : 4 * a.length
            },
            toString: function(a) {
                return (a || v).stringify(this)
            },
            concat: function(a) {
                var c = this.words,
                    e = a.words,
                    j = this.sigBytes;
                a = a.sigBytes;
                this.clamp();
                if (j % 4)
                    for (var k = 0; k < a; k++) c[j + k >>> 2] |= (e[k >>> 2] >>> 24 - 8 * (k % 4) & 255) << 24 - 8 * ((j + k) % 4);
                else if (65535 < e.length)
                    for (k = 0; k < a; k += 4) c[j + k >>> 2] = e[k >>> 2];
                else c.push.apply(c, e);
                this.sigBytes += a;
                return this
            },
            clamp: function() {
                var a = this.words,
                    c = this.sigBytes;
                a[c >>> 2] &= 4294967295 <<
                    32 - 8 * (c % 4);
                a.length = u.ceil(c / 4)
            },
            clone: function() {
                var a = t.clone.call(this);
                a.words = this.words.slice(0);
                return a
            },
            random: function(a) {
                for (var c = [], e = 0; e < a; e += 4) c.push(4294967296 * u.random() | 0);
                return new r.init(c, a)
            }
        }),
        w = d.enc = {},
        v = w.Hex = {
            stringify: function(a) {
                var c = a.words;
                a = a.sigBytes;
                for (var e = [], j = 0; j < a; j++) {
                    var k = c[j >>> 2] >>> 24 - 8 * (j % 4) & 255;
                    e.push((k >>> 4).toString(16));
                    e.push((k & 15).toString(16))
                }
                return e.join("")
            },
            parse: function(a) {
                for (var c = a.length, e = [], j = 0; j < c; j += 2) e[j >>> 3] |= parseInt(a.substr(j,
                    2), 16) << 24 - 4 * (j % 8);
                return new r.init(e, c / 2)
            }
        },
        b = w.Latin1 = {
            stringify: function(a) {
                var c = a.words;
                a = a.sigBytes;
                for (var e = [], j = 0; j < a; j++) e.push(String.fromCharCode(c[j >>> 2] >>> 24 - 8 * (j % 4) & 255));
                return e.join("")
            },
            parse: function(a) {
                for (var c = a.length, e = [], j = 0; j < c; j++) e[j >>> 2] |= (a.charCodeAt(j) & 255) << 24 - 8 * (j % 4);
                return new r.init(e, c)
            }
        },
        x = w.Utf8 = {
            stringify: function(a) {
                try {
                    return decodeURIComponent(escape(b.stringify(a)))
                } catch (c) {
                    throw Error("Malformed UTF-8 data");
                }
            },
            parse: function(a) {
                return b.parse(unescape(encodeURIComponent(a)))
            }
        },
        q = l.BufferedBlockAlgorithm = t.extend({
            reset: function() {
                this._data = new r.init;
                this._nDataBytes = 0
            },
            _append: function(a) {
                "string" == typeof a && (a = x.parse(a));
                this._data.concat(a);
                this._nDataBytes += a.sigBytes
            },
            _process: function(a) {
                var c = this._data,
                    e = c.words,
                    j = c.sigBytes,
                    k = this.blockSize,
                    b = j / (4 * k),
                    b = a ? u.ceil(b) : u.max((b | 0) - this._minBufferSize, 0);
                a = b * k;
                j = u.min(4 * a, j);
                if (a) {
                    for (var q = 0; q < a; q += k) this._doProcessBlock(e, q);
                    q = e.splice(0, a);
                    c.sigBytes -= j
                }
                return new r.init(q, j)
            },
            clone: function() {
                var a = t.clone.call(this);
                a._data = this._data.clone();
                return a
            },
            _minBufferSize: 0
        });
    l.Hasher = q.extend({
        cfg: t.extend(),
        init: function(a) {
            this.cfg = this.cfg.extend(a);
            this.reset()
        },
        reset: function() {
            q.reset.call(this);
            this._doReset()
        },
        update: function(a) {
            this._append(a);
            this._process();
            return this
        },
        finalize: function(a) {
            a && this._append(a);
            return this._doFinalize()
        },
        blockSize: 16,
        _createHelper: function(a) {
            return function(b, e) {
                return (new a.init(e)).finalize(b)
            }
        },
        _createHmacHelper: function(a) {
            return function(b, e) {
                return (new n.HMAC.init(a,
                    e)).finalize(b)
            }
        }
    });
    var n = d.algo = {};
    return d
}(Math);
(function() {
    var u = CryptoJS,
        p = u.lib.WordArray;
    u.enc.Base64 = {
        stringify: function(d) {
            var l = d.words,
                p = d.sigBytes,
                t = this._map;
            d.clamp();
            d = [];
            for (var r = 0; r < p; r += 3)
                for (var w = (l[r >>> 2] >>> 24 - 8 * (r % 4) & 255) << 16 | (l[r + 1 >>> 2] >>> 24 - 8 * ((r + 1) % 4) & 255) << 8 | l[r + 2 >>> 2] >>> 24 - 8 * ((r + 2) % 4) & 255, v = 0; 4 > v && r + 0.75 * v < p; v++) d.push(t.charAt(w >>> 6 * (3 - v) & 63));
            if (l = t.charAt(64))
                for (; d.length % 4;) d.push(l);
            return d.join("")
        },
        parse: function(d) {
            var l = d.length,
                s = this._map,
                t = s.charAt(64);
            t && (t = d.indexOf(t), -1 != t && (l = t));
            for (var t = [], r = 0, w = 0; w <
                l; w++)
                if (w % 4) {
                    var v = s.indexOf(d.charAt(w - 1)) << 2 * (w % 4),
                        b = s.indexOf(d.charAt(w)) >>> 6 - 2 * (w % 4);
                    t[r >>> 2] |= (v | b) << 24 - 8 * (r % 4);
                    r++
                }
            return p.create(t, r)
        },
        _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
    }
})();
(function(u) {
    function p(b, n, a, c, e, j, k) {
        b = b + (n & a | ~n & c) + e + k;
        return (b << j | b >>> 32 - j) + n
    }

    function d(b, n, a, c, e, j, k) {
        b = b + (n & c | a & ~c) + e + k;
        return (b << j | b >>> 32 - j) + n
    }

    function l(b, n, a, c, e, j, k) {
        b = b + (n ^ a ^ c) + e + k;
        return (b << j | b >>> 32 - j) + n
    }

    function s(b, n, a, c, e, j, k) {
        b = b + (a ^ (n | ~c)) + e + k;
        return (b << j | b >>> 32 - j) + n
    }
    for (var t = CryptoJS, r = t.lib, w = r.WordArray, v = r.Hasher, r = t.algo, b = [], x = 0; 64 > x; x++) b[x] = 4294967296 * u.abs(u.sin(x + 1)) | 0;
    r = r.MD5 = v.extend({
        _doReset: function() {
            this._hash = new w.init([1732584193, 4023233417, 2562383102, 271733878])
        },
        _doProcessBlock: function(q, n) {
            for (var a = 0; 16 > a; a++) {
                var c = n + a,
                    e = q[c];
                q[c] = (e << 8 | e >>> 24) & 16711935 | (e << 24 | e >>> 8) & 4278255360
            }
            var a = this._hash.words,
                c = q[n + 0],
                e = q[n + 1],
                j = q[n + 2],
                k = q[n + 3],
                z = q[n + 4],
                r = q[n + 5],
                t = q[n + 6],
                w = q[n + 7],
                v = q[n + 8],
                A = q[n + 9],
                B = q[n + 10],
                C = q[n + 11],
                u = q[n + 12],
                D = q[n + 13],
                E = q[n + 14],
                x = q[n + 15],
                f = a[0],
                m = a[1],
                g = a[2],
                h = a[3],
                f = p(f, m, g, h, c, 7, b[0]),
                h = p(h, f, m, g, e, 12, b[1]),
                g = p(g, h, f, m, j, 17, b[2]),
                m = p(m, g, h, f, k, 22, b[3]),
                f = p(f, m, g, h, z, 7, b[4]),
                h = p(h, f, m, g, r, 12, b[5]),
                g = p(g, h, f, m, t, 17, b[6]),
                m = p(m, g, h, f, w, 22, b[7]),
                f = p(f, m, g, h, v, 7, b[8]),
                h = p(h, f, m, g, A, 12, b[9]),
                g = p(g, h, f, m, B, 17, b[10]),
                m = p(m, g, h, f, C, 22, b[11]),
                f = p(f, m, g, h, u, 7, b[12]),
                h = p(h, f, m, g, D, 12, b[13]),
                g = p(g, h, f, m, E, 17, b[14]),
                m = p(m, g, h, f, x, 22, b[15]),
                f = d(f, m, g, h, e, 5, b[16]),
                h = d(h, f, m, g, t, 9, b[17]),
                g = d(g, h, f, m, C, 14, b[18]),
                m = d(m, g, h, f, c, 20, b[19]),
                f = d(f, m, g, h, r, 5, b[20]),
                h = d(h, f, m, g, B, 9, b[21]),
                g = d(g, h, f, m, x, 14, b[22]),
                m = d(m, g, h, f, z, 20, b[23]),
                f = d(f, m, g, h, A, 5, b[24]),
                h = d(h, f, m, g, E, 9, b[25]),
                g = d(g, h, f, m, k, 14, b[26]),
                m = d(m, g, h, f, v, 20, b[27]),
                f = d(f, m, g, h, D, 5, b[28]),
                h = d(h, f,
                    m, g, j, 9, b[29]),
                g = d(g, h, f, m, w, 14, b[30]),
                m = d(m, g, h, f, u, 20, b[31]),
                f = l(f, m, g, h, r, 4, b[32]),
                h = l(h, f, m, g, v, 11, b[33]),
                g = l(g, h, f, m, C, 16, b[34]),
                m = l(m, g, h, f, E, 23, b[35]),
                f = l(f, m, g, h, e, 4, b[36]),
                h = l(h, f, m, g, z, 11, b[37]),
                g = l(g, h, f, m, w, 16, b[38]),
                m = l(m, g, h, f, B, 23, b[39]),
                f = l(f, m, g, h, D, 4, b[40]),
                h = l(h, f, m, g, c, 11, b[41]),
                g = l(g, h, f, m, k, 16, b[42]),
                m = l(m, g, h, f, t, 23, b[43]),
                f = l(f, m, g, h, A, 4, b[44]),
                h = l(h, f, m, g, u, 11, b[45]),
                g = l(g, h, f, m, x, 16, b[46]),
                m = l(m, g, h, f, j, 23, b[47]),
                f = s(f, m, g, h, c, 6, b[48]),
                h = s(h, f, m, g, w, 10, b[49]),
                g = s(g, h, f, m,
                    E, 15, b[50]),
                m = s(m, g, h, f, r, 21, b[51]),
                f = s(f, m, g, h, u, 6, b[52]),
                h = s(h, f, m, g, k, 10, b[53]),
                g = s(g, h, f, m, B, 15, b[54]),
                m = s(m, g, h, f, e, 21, b[55]),
                f = s(f, m, g, h, v, 6, b[56]),
                h = s(h, f, m, g, x, 10, b[57]),
                g = s(g, h, f, m, t, 15, b[58]),
                m = s(m, g, h, f, D, 21, b[59]),
                f = s(f, m, g, h, z, 6, b[60]),
                h = s(h, f, m, g, C, 10, b[61]),
                g = s(g, h, f, m, j, 15, b[62]),
                m = s(m, g, h, f, A, 21, b[63]);
            a[0] = a[0] + f | 0;
            a[1] = a[1] + m | 0;
            a[2] = a[2] + g | 0;
            a[3] = a[3] + h | 0
        },
        _doFinalize: function() {
            var b = this._data,
                n = b.words,
                a = 8 * this._nDataBytes,
                c = 8 * b.sigBytes;
            n[c >>> 5] |= 128 << 24 - c % 32;
            var e = u.floor(a /
                4294967296);
            n[(c + 64 >>> 9 << 4) + 15] = (e << 8 | e >>> 24) & 16711935 | (e << 24 | e >>> 8) & 4278255360;
            n[(c + 64 >>> 9 << 4) + 14] = (a << 8 | a >>> 24) & 16711935 | (a << 24 | a >>> 8) & 4278255360;
            b.sigBytes = 4 * (n.length + 1);
            this._process();
            b = this._hash;
            n = b.words;
            for (a = 0; 4 > a; a++) c = n[a], n[a] = (c << 8 | c >>> 24) & 16711935 | (c << 24 | c >>> 8) & 4278255360;
            return b
        },
        clone: function() {
            var b = v.clone.call(this);
            b._hash = this._hash.clone();
            return b
        }
    });
    t.MD5 = v._createHelper(r);
    t.HmacMD5 = v._createHmacHelper(r)
})(Math);
(function() {
    var u = CryptoJS,
        p = u.lib,
        d = p.Base,
        l = p.WordArray,
        p = u.algo,
        s = p.EvpKDF = d.extend({
            cfg: d.extend({
                keySize: 4,
                hasher: p.MD5,
                iterations: 1
            }),
            init: function(d) {
                this.cfg = this.cfg.extend(d)
            },
            compute: function(d, r) {
                for (var p = this.cfg, s = p.hasher.create(), b = l.create(), u = b.words, q = p.keySize, p = p.iterations; u.length < q;) {
                    n && s.update(n);
                    var n = s.update(d).finalize(r);
                    s.reset();
                    for (var a = 1; a < p; a++) n = s.finalize(n), s.reset();
                    b.concat(n)
                }
                b.sigBytes = 4 * q;
                return b
            }
        });
    u.EvpKDF = function(d, l, p) {
        return s.create(p).compute(d,
            l)
    }
})();
CryptoJS.lib.Cipher || function(u) {
    var p = CryptoJS,
        d = p.lib,
        l = d.Base,
        s = d.WordArray,
        t = d.BufferedBlockAlgorithm,
        r = p.enc.Base64,
        w = p.algo.EvpKDF,
        v = d.Cipher = t.extend({
            cfg: l.extend(),
            createEncryptor: function(e, a) {
                return this.create(this._ENC_XFORM_MODE, e, a)
            },
            createDecryptor: function(e, a) {
                return this.create(this._DEC_XFORM_MODE, e, a)
            },
            init: function(e, a, b) {
                this.cfg = this.cfg.extend(b);
                this._xformMode = e;
                this._key = a;
                this.reset()
            },
            reset: function() {
                t.reset.call(this);
                this._doReset()
            },
            process: function(e) {
                this._append(e);
                return this._process()
            },
            finalize: function(e) {
                e && this._append(e);
                return this._doFinalize()
            },
            keySize: 4,
            ivSize: 4,
            _ENC_XFORM_MODE: 1,
            _DEC_XFORM_MODE: 2,
            _createHelper: function(e) {
                return {
                    encrypt: function(b, k, d) {
                        return ("string" == typeof k ? c : a).encrypt(e, b, k, d)
                    },
                    decrypt: function(b, k, d) {
                        return ("string" == typeof k ? c : a).decrypt(e, b, k, d)
                    }
                }
            }
        });
    d.StreamCipher = v.extend({
        _doFinalize: function() {
            return this._process(!0)
        },
        blockSize: 1
    });
    var b = p.mode = {},
        x = function(e, a, b) {
            var c = this._iv;
            c ? this._iv = u : c = this._prevBlock;
            for (var d = 0; d < b; d++) e[a + d] ^=
                c[d]
        },
        q = (d.BlockCipherMode = l.extend({
            createEncryptor: function(e, a) {
                return this.Encryptor.create(e, a)
            },
            createDecryptor: function(e, a) {
                return this.Decryptor.create(e, a)
            },
            init: function(e, a) {
                this._cipher = e;
                this._iv = a
            }
        })).extend();
    q.Encryptor = q.extend({
        processBlock: function(e, a) {
            var b = this._cipher,
                c = b.blockSize;
            x.call(this, e, a, c);
            b.encryptBlock(e, a);
            this._prevBlock = e.slice(a, a + c)
        }
    });
    q.Decryptor = q.extend({
        processBlock: function(e, a) {
            var b = this._cipher,
                c = b.blockSize,
                d = e.slice(a, a + c);
            b.decryptBlock(e, a);
            x.call(this,
                e, a, c);
            this._prevBlock = d
        }
    });
    b = b.CBC = q;
    q = (p.pad = {}).Pkcs7 = {
        pad: function(a, b) {
            for (var c = 4 * b, c = c - a.sigBytes % c, d = c << 24 | c << 16 | c << 8 | c, l = [], n = 0; n < c; n += 4) l.push(d);
            c = s.create(l, c);
            a.concat(c)
        },
        unpad: function(a) {
            a.sigBytes -= a.words[a.sigBytes - 1 >>> 2] & 255
        }
    };
    d.BlockCipher = v.extend({
        cfg: v.cfg.extend({
            mode: b,
            padding: q
        }),
        reset: function() {
            v.reset.call(this);
            var a = this.cfg,
                b = a.iv,
                a = a.mode;
            if (this._xformMode == this._ENC_XFORM_MODE) var c = a.createEncryptor;
            else c = a.createDecryptor, this._minBufferSize = 1;
            this._mode = c.call(a,
                this, b && b.words)
        },
        _doProcessBlock: function(a, b) {
            this._mode.processBlock(a, b)
        },
        _doFinalize: function() {
            var a = this.cfg.padding;
            if (this._xformMode == this._ENC_XFORM_MODE) {
                a.pad(this._data, this.blockSize);
                var b = this._process(!0)
            } else b = this._process(!0), a.unpad(b);
            return b
        },
        blockSize: 4
    });
    var n = d.CipherParams = l.extend({
            init: function(a) {
                this.mixIn(a)
            },
            toString: function(a) {
                return (a || this.formatter).stringify(this)
            }
        }),
        b = (p.format = {}).OpenSSL = {
            stringify: function(a) {
                var b = a.ciphertext;
                a = a.salt;
                return (a ? s.create([1398893684,
                    1701076831
                ]).concat(a).concat(b) : b).toString(r)
            },
            parse: function(a) {
                a = r.parse(a);
                var b = a.words;
                if (1398893684 == b[0] && 1701076831 == b[1]) {
                    var c = s.create(b.slice(2, 4));
                    b.splice(0, 4);
                    a.sigBytes -= 16
                }
                return n.create({
                    ciphertext: a,
                    salt: c
                })
            }
        },
        a = d.SerializableCipher = l.extend({
            cfg: l.extend({
                format: b
            }),
            encrypt: function(a, b, c, d) {
                d = this.cfg.extend(d);
                var l = a.createEncryptor(c, d);
                b = l.finalize(b);
                l = l.cfg;
                return n.create({
                    ciphertext: b,
                    key: c,
                    iv: l.iv,
                    algorithm: a,
                    mode: l.mode,
                    padding: l.padding,
                    blockSize: a.blockSize,
                    formatter: d.format
                })
            },
            decrypt: function(a, b, c, d) {
                d = this.cfg.extend(d);
                b = this._parse(b, d.format);
                return a.createDecryptor(c, d).finalize(b.ciphertext)
            },
            _parse: function(a, b) {
                return "string" == typeof a ? b.parse(a, this) : a
            }
        }),
        p = (p.kdf = {}).OpenSSL = {
            execute: function(a, b, c, d) {
                d || (d = s.random(8));
                a = w.create({
                    keySize: b + c
                }).compute(a, d);
                c = s.create(a.words.slice(b), 4 * c);
                a.sigBytes = 4 * b;
                return n.create({
                    key: a,
                    iv: c,
                    salt: d
                })
            }
        },
        c = d.PasswordBasedCipher = a.extend({
            cfg: a.cfg.extend({
                kdf: p
            }),
            encrypt: function(b, c, d, l) {
                l = this.cfg.extend(l);
                d = l.kdf.execute(d,
                    b.keySize, b.ivSize);
                l.iv = d.iv;
                b = a.encrypt.call(this, b, c, d.key, l);
                b.mixIn(d);
                return b
            },
            decrypt: function(b, c, d, l) {
                l = this.cfg.extend(l);
                c = this._parse(c, l.format);
                d = l.kdf.execute(d, b.keySize, b.ivSize, c.salt);
                l.iv = d.iv;
                return a.decrypt.call(this, b, c, d.key, l)
            }
        })
}();
(function() {
    for (var u = CryptoJS, p = u.lib.BlockCipher, d = u.algo, l = [], s = [], t = [], r = [], w = [], v = [], b = [], x = [], q = [], n = [], a = [], c = 0; 256 > c; c++) a[c] = 128 > c ? c << 1 : c << 1 ^ 283;
    for (var e = 0, j = 0, c = 0; 256 > c; c++) {
        var k = j ^ j << 1 ^ j << 2 ^ j << 3 ^ j << 4,
            k = k >>> 8 ^ k & 255 ^ 99;
        l[e] = k;
        s[k] = e;
        var z = a[e],
            F = a[z],
            G = a[F],
            y = 257 * a[k] ^ 16843008 * k;
        t[e] = y << 24 | y >>> 8;
        r[e] = y << 16 | y >>> 16;
        w[e] = y << 8 | y >>> 24;
        v[e] = y;
        y = 16843009 * G ^ 65537 * F ^ 257 * z ^ 16843008 * e;
        b[k] = y << 24 | y >>> 8;
        x[k] = y << 16 | y >>> 16;
        q[k] = y << 8 | y >>> 24;
        n[k] = y;
        e ? (e = z ^ a[a[a[G ^ z]]], j ^= a[a[j]]) : e = j = 1
    }
    var H = [0, 1, 2, 4, 8,
            16, 32, 64, 128, 27, 54
        ],
        d = d.AES = p.extend({
            _doReset: function() {
                for (var a = this._key, c = a.words, d = a.sigBytes / 4, a = 4 * ((this._nRounds = d + 6) + 1), e = this._keySchedule = [], j = 0; j < a; j++)
                    if (j < d) e[j] = c[j];
                    else {
                        var k = e[j - 1];
                        j % d ? 6 < d && 4 == j % d && (k = l[k >>> 24] << 24 | l[k >>> 16 & 255] << 16 | l[k >>> 8 & 255] << 8 | l[k & 255]) : (k = k << 8 | k >>> 24, k = l[k >>> 24] << 24 | l[k >>> 16 & 255] << 16 | l[k >>> 8 & 255] << 8 | l[k & 255], k ^= H[j / d | 0] << 24);
                        e[j] = e[j - d] ^ k
                    }
                c = this._invKeySchedule = [];
                for (d = 0; d < a; d++) j = a - d, k = d % 4 ? e[j] : e[j - 4], c[d] = 4 > d || 4 >= j ? k : b[l[k >>> 24]] ^ x[l[k >>> 16 & 255]] ^ q[l[k >>>
                    8 & 255]] ^ n[l[k & 255]]
            },
            encryptBlock: function(a, b) {
                this._doCryptBlock(a, b, this._keySchedule, t, r, w, v, l)
            },
            decryptBlock: function(a, c) {
                var d = a[c + 1];
                a[c + 1] = a[c + 3];
                a[c + 3] = d;
                this._doCryptBlock(a, c, this._invKeySchedule, b, x, q, n, s);
                d = a[c + 1];
                a[c + 1] = a[c + 3];
                a[c + 3] = d
            },
            _doCryptBlock: function(a, b, c, d, e, j, l, f) {
                for (var m = this._nRounds, g = a[b] ^ c[0], h = a[b + 1] ^ c[1], k = a[b + 2] ^ c[2], n = a[b + 3] ^ c[3], p = 4, r = 1; r < m; r++) var q = d[g >>> 24] ^ e[h >>> 16 & 255] ^ j[k >>> 8 & 255] ^ l[n & 255] ^ c[p++],
                    s = d[h >>> 24] ^ e[k >>> 16 & 255] ^ j[n >>> 8 & 255] ^ l[g & 255] ^ c[p++],
                    t =
                    d[k >>> 24] ^ e[n >>> 16 & 255] ^ j[g >>> 8 & 255] ^ l[h & 255] ^ c[p++],
                    n = d[n >>> 24] ^ e[g >>> 16 & 255] ^ j[h >>> 8 & 255] ^ l[k & 255] ^ c[p++],
                    g = q,
                    h = s,
                    k = t;
                q = (f[g >>> 24] << 24 | f[h >>> 16 & 255] << 16 | f[k >>> 8 & 255] << 8 | f[n & 255]) ^ c[p++];
                s = (f[h >>> 24] << 24 | f[k >>> 16 & 255] << 16 | f[n >>> 8 & 255] << 8 | f[g & 255]) ^ c[p++];
                t = (f[k >>> 24] << 24 | f[n >>> 16 & 255] << 16 | f[g >>> 8 & 255] << 8 | f[h & 255]) ^ c[p++];
                n = (f[n >>> 24] << 24 | f[g >>> 16 & 255] << 16 | f[h >>> 8 & 255] << 8 | f[k & 255]) ^ c[p++];
                a[b] = q;
                a[b + 1] = s;
                a[b + 2] = t;
                a[b + 3] = n
            },
            keySize: 8
        });
    u.AES = p._createHelper(d)
})();

module.exports = CryptoJS

第二步:在一個新的Js文件內  封裝加密和解密方法 ;

var CryptoJS = require('../aes.js'); //引用AES源碼js
var key =CryptoJS.enc.Utf8.parse('0000000000000000'); //十六位十六進制數作為秘鑰  (后端提供,或者說明)
var iv = CryptoJS.enc.Utf8.parse('0000000000000000');//十六位十六進制數作為秘鑰偏移量 (后端提供,或者說明)
//解密方法(CBC模式)
function Decrypt(word) {
    var encryptedHexStr = CryptoJS.enc.Hex.parse(word);
    var srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
    var decrypt = CryptoJS.AES.decrypt(srcs, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
    return decryptedStr.toString();
}
//加密方法
function crypt(word) {
    var srcs = CryptoJS.enc.Utf8.parse(word);
    var encrypted = CryptoJS.AES.encrypt(srcs, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    return encrypted.ciphertext.toString().toUpperCase();
}

//暴露接口
module.exports.decrypt = Decrypt;
module.exports.Crypt = crypt;

第三步: 跟上面一樣在需要加密的地方引入 加密解密方法 就好了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM