You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			864 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			JavaScript
		
	
			
		
		
	
	
			864 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			JavaScript
		
	
| /*
 | |
| CryptoJS v3.1.2
 | |
| code.google.com/p/crypto-js
 | |
| (c) 2009-2013 by Jeff Mott. All rights reserved.
 | |
| code.google.com/p/crypto-js/wiki/License
 | |
| */
 | |
| /**
 | |
|  * Cipher core components.
 | |
|  */
 | |
| CryptoJS.lib.Cipher || (function (undefined) {
 | |
|     // Shortcuts
 | |
|     var C = CryptoJS;
 | |
|     var C_lib = C.lib;
 | |
|     var Base = C_lib.Base;
 | |
|     var WordArray = C_lib.WordArray;
 | |
|     var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;
 | |
|     var C_enc = C.enc;
 | |
|     var Utf8 = C_enc.Utf8;
 | |
|     var Base64 = C_enc.Base64;
 | |
|     var C_algo = C.algo;
 | |
|     var EvpKDF = C_algo.EvpKDF;
 | |
| 
 | |
|     /**
 | |
|      * Abstract base cipher template.
 | |
|      *
 | |
|      * @property {number} keySize This cipher's key size. Default: 4 (128 bits)
 | |
|      * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)
 | |
|      * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.
 | |
|      * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.
 | |
|      */
 | |
|     var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({
 | |
|         /**
 | |
|          * Configuration options.
 | |
|          *
 | |
|          * @property {WordArray} iv The IV to use for this operation.
 | |
|          */
 | |
|         cfg: Base.extend(),
 | |
| 
 | |
|         /**
 | |
|          * Creates this cipher in encryption mode.
 | |
|          *
 | |
|          * @param {WordArray} key The key.
 | |
|          * @param {Object} cfg (Optional) The configuration options to use for this operation.
 | |
|          *
 | |
|          * @return {Cipher} A cipher instance.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });
 | |
|          */
 | |
|         createEncryptor: function (key, cfg) {
 | |
|             return this.create(this._ENC_XFORM_MODE, key, cfg);
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Creates this cipher in decryption mode.
 | |
|          *
 | |
|          * @param {WordArray} key The key.
 | |
|          * @param {Object} cfg (Optional) The configuration options to use for this operation.
 | |
|          *
 | |
|          * @return {Cipher} A cipher instance.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });
 | |
|          */
 | |
|         createDecryptor: function (key, cfg) {
 | |
|             return this.create(this._DEC_XFORM_MODE, key, cfg);
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Initializes a newly created cipher.
 | |
|          *
 | |
|          * @param {number} xformMode Either the encryption or decryption transormation mode constant.
 | |
|          * @param {WordArray} key The key.
 | |
|          * @param {Object} cfg (Optional) The configuration options to use for this operation.
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });
 | |
|          */
 | |
|         init: function (xformMode, key, cfg) {
 | |
|             // Apply config defaults
 | |
|             this.cfg = this.cfg.extend(cfg);
 | |
| 
 | |
|             // Store transform mode and key
 | |
|             this._xformMode = xformMode;
 | |
|             this._key = key;
 | |
| 
 | |
|             // Set initial values
 | |
|             this.reset();
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Resets this cipher to its initial state.
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     cipher.reset();
 | |
|          */
 | |
|         reset: function () {
 | |
|             // Reset data buffer
 | |
|             BufferedBlockAlgorithm.reset.call(this);
 | |
| 
 | |
|             // Perform concrete-cipher logic
 | |
|             this._doReset();
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Adds data to be encrypted or decrypted.
 | |
|          *
 | |
|          * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.
 | |
|          *
 | |
|          * @return {WordArray} The data after processing.
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var encrypted = cipher.process('data');
 | |
|          *     var encrypted = cipher.process(wordArray);
 | |
|          */
 | |
|         process: function (dataUpdate) {
 | |
|             // Append
 | |
|             this._append(dataUpdate);
 | |
| 
 | |
|             // Process available blocks
 | |
|             return this._process();
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Finalizes the encryption or decryption process.
 | |
|          * Note that the finalize operation is effectively a destructive, read-once operation.
 | |
|          *
 | |
|          * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.
 | |
|          *
 | |
|          * @return {WordArray} The data after final processing.
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var encrypted = cipher.finalize();
 | |
|          *     var encrypted = cipher.finalize('data');
 | |
|          *     var encrypted = cipher.finalize(wordArray);
 | |
|          */
 | |
|         finalize: function (dataUpdate) {
 | |
|             // Final data update
 | |
|             if (dataUpdate) {
 | |
|                 this._append(dataUpdate);
 | |
|             }
 | |
| 
 | |
|             // Perform concrete-cipher logic
 | |
|             var finalProcessedData = this._doFinalize();
 | |
| 
 | |
|             return finalProcessedData;
 | |
|         },
 | |
| 
 | |
|         keySize: 128/32,
 | |
| 
 | |
|         ivSize: 128/32,
 | |
| 
 | |
|         _ENC_XFORM_MODE: 1,
 | |
| 
 | |
|         _DEC_XFORM_MODE: 2,
 | |
| 
 | |
|         /**
 | |
|          * Creates shortcut functions to a cipher's object interface.
 | |
|          *
 | |
|          * @param {Cipher} cipher The cipher to create a helper for.
 | |
|          *
 | |
|          * @return {Object} An object with encrypt and decrypt shortcut functions.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);
 | |
|          */
 | |
|         _createHelper: (function () {
 | |
|             function selectCipherStrategy(key) {
 | |
|                 if (typeof key == 'string') {
 | |
|                     return PasswordBasedCipher;
 | |
|                 } else {
 | |
|                     return SerializableCipher;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return function (cipher) {
 | |
|                 return {
 | |
|                     encrypt: function (message, key, cfg) {
 | |
|                         return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);
 | |
|                     },
 | |
| 
 | |
|                     decrypt: function (ciphertext, key, cfg) {
 | |
|                         return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);
 | |
|                     }
 | |
|                 };
 | |
|             };
 | |
|         }())
 | |
|     });
 | |
| 
 | |
|     /**
 | |
|      * Abstract base stream cipher template.
 | |
|      *
 | |
|      * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)
 | |
|      */
 | |
|     var StreamCipher = C_lib.StreamCipher = Cipher.extend({
 | |
|         _doFinalize: function () {
 | |
|             // Process partial blocks
 | |
|             var finalProcessedBlocks = this._process(!!'flush');
 | |
| 
 | |
|             return finalProcessedBlocks;
 | |
|         },
 | |
| 
 | |
|         blockSize: 1
 | |
|     });
 | |
| 
 | |
|     /**
 | |
|      * Mode namespace.
 | |
|      */
 | |
|     var C_mode = C.mode = {};
 | |
| 
 | |
|     /**
 | |
|      * Abstract base block cipher mode template.
 | |
|      */
 | |
|     var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({
 | |
|         /**
 | |
|          * Creates this mode for encryption.
 | |
|          *
 | |
|          * @param {Cipher} cipher A block cipher instance.
 | |
|          * @param {Array} iv The IV words.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);
 | |
|          */
 | |
|         createEncryptor: function (cipher, iv) {
 | |
|             return this.Encryptor.create(cipher, iv);
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Creates this mode for decryption.
 | |
|          *
 | |
|          * @param {Cipher} cipher A block cipher instance.
 | |
|          * @param {Array} iv The IV words.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);
 | |
|          */
 | |
|         createDecryptor: function (cipher, iv) {
 | |
|             return this.Decryptor.create(cipher, iv);
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Initializes a newly created mode.
 | |
|          *
 | |
|          * @param {Cipher} cipher A block cipher instance.
 | |
|          * @param {Array} iv The IV words.
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);
 | |
|          */
 | |
|         init: function (cipher, iv) {
 | |
|             this._cipher = cipher;
 | |
|             this._iv = iv;
 | |
|         }
 | |
|     });
 | |
| 
 | |
|     /**
 | |
|      * Cipher Block Chaining mode.
 | |
|      */
 | |
|     var CBC = C_mode.CBC = (function () {
 | |
|         /**
 | |
|          * Abstract base CBC mode.
 | |
|          */
 | |
|         var CBC = BlockCipherMode.extend();
 | |
| 
 | |
|         /**
 | |
|          * CBC encryptor.
 | |
|          */
 | |
|         CBC.Encryptor = CBC.extend({
 | |
|             /**
 | |
|              * Processes the data block at offset.
 | |
|              *
 | |
|              * @param {Array} words The data words to operate on.
 | |
|              * @param {number} offset The offset where the block starts.
 | |
|              *
 | |
|              * @example
 | |
|              *
 | |
|              *     mode.processBlock(data.words, offset);
 | |
|              */
 | |
|             processBlock: function (words, offset) {
 | |
|                 // Shortcuts
 | |
|                 var cipher = this._cipher;
 | |
|                 var blockSize = cipher.blockSize;
 | |
| 
 | |
|                 // XOR and encrypt
 | |
|                 xorBlock.call(this, words, offset, blockSize);
 | |
|                 cipher.encryptBlock(words, offset);
 | |
| 
 | |
|                 // Remember this block to use with next block
 | |
|                 this._prevBlock = words.slice(offset, offset + blockSize);
 | |
|             }
 | |
|         });
 | |
| 
 | |
|         /**
 | |
|          * CBC decryptor.
 | |
|          */
 | |
|         CBC.Decryptor = CBC.extend({
 | |
|             /**
 | |
|              * Processes the data block at offset.
 | |
|              *
 | |
|              * @param {Array} words The data words to operate on.
 | |
|              * @param {number} offset The offset where the block starts.
 | |
|              *
 | |
|              * @example
 | |
|              *
 | |
|              *     mode.processBlock(data.words, offset);
 | |
|              */
 | |
|             processBlock: function (words, offset) {
 | |
|                 // Shortcuts
 | |
|                 var cipher = this._cipher;
 | |
|                 var blockSize = cipher.blockSize;
 | |
| 
 | |
|                 // Remember this block to use with next block
 | |
|                 var thisBlock = words.slice(offset, offset + blockSize);
 | |
| 
 | |
|                 // Decrypt and XOR
 | |
|                 cipher.decryptBlock(words, offset);
 | |
|                 xorBlock.call(this, words, offset, blockSize);
 | |
| 
 | |
|                 // This block becomes the previous block
 | |
|                 this._prevBlock = thisBlock;
 | |
|             }
 | |
|         });
 | |
| 
 | |
|         function xorBlock(words, offset, blockSize) {
 | |
|             // Shortcut
 | |
|             var iv = this._iv;
 | |
| 
 | |
|             // Choose mixing block
 | |
|             if (iv) {
 | |
|                 var block = iv;
 | |
| 
 | |
|                 // Remove IV for subsequent blocks
 | |
|                 this._iv = undefined;
 | |
|             } else {
 | |
|                 var block = this._prevBlock;
 | |
|             }
 | |
| 
 | |
|             // XOR blocks
 | |
|             for (var i = 0; i < blockSize; i++) {
 | |
|                 words[offset + i] ^= block[i];
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return CBC;
 | |
|     }());
 | |
| 
 | |
|     /**
 | |
|      * Padding namespace.
 | |
|      */
 | |
|     var C_pad = C.pad = {};
 | |
| 
 | |
|     /**
 | |
|      * PKCS #5/7 padding strategy.
 | |
|      */
 | |
|     var Pkcs7 = C_pad.Pkcs7 = {
 | |
|         /**
 | |
|          * Pads data using the algorithm defined in PKCS #5/7.
 | |
|          *
 | |
|          * @param {WordArray} data The data to pad.
 | |
|          * @param {number} blockSize The multiple that the data should be padded to.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     CryptoJS.pad.Pkcs7.pad(wordArray, 4);
 | |
|          */
 | |
|         pad: function (data, blockSize) {
 | |
|             // Shortcut
 | |
|             var blockSizeBytes = blockSize * 4;
 | |
| 
 | |
|             // Count padding bytes
 | |
|             var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
 | |
| 
 | |
|             // Create padding word
 | |
|             var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;
 | |
| 
 | |
|             // Create padding
 | |
|             var paddingWords = [];
 | |
|             for (var i = 0; i < nPaddingBytes; i += 4) {
 | |
|                 paddingWords.push(paddingWord);
 | |
|             }
 | |
|             var padding = WordArray.create(paddingWords, nPaddingBytes);
 | |
| 
 | |
|             // Add padding
 | |
|             data.concat(padding);
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Unpads data that had been padded using the algorithm defined in PKCS #5/7.
 | |
|          *
 | |
|          * @param {WordArray} data The data to unpad.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     CryptoJS.pad.Pkcs7.unpad(wordArray);
 | |
|          */
 | |
|         unpad: function (data) {
 | |
|             // Get number of padding bytes from last byte
 | |
|             var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
 | |
| 
 | |
|             // Remove padding
 | |
|             data.sigBytes -= nPaddingBytes;
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     /**
 | |
|      * Abstract base block cipher template.
 | |
|      *
 | |
|      * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)
 | |
|      */
 | |
|     var BlockCipher = C_lib.BlockCipher = Cipher.extend({
 | |
|         /**
 | |
|          * Configuration options.
 | |
|          *
 | |
|          * @property {Mode} mode The block mode to use. Default: CBC
 | |
|          * @property {Padding} padding The padding strategy to use. Default: Pkcs7
 | |
|          */
 | |
|         cfg: Cipher.cfg.extend({
 | |
|             mode: CBC,
 | |
|             padding: Pkcs7
 | |
|         }),
 | |
| 
 | |
|         reset: function () {
 | |
|             // Reset cipher
 | |
|             Cipher.reset.call(this);
 | |
| 
 | |
|             // Shortcuts
 | |
|             var cfg = this.cfg;
 | |
|             var iv = cfg.iv;
 | |
|             var mode = cfg.mode;
 | |
| 
 | |
|             // Reset block mode
 | |
|             if (this._xformMode == this._ENC_XFORM_MODE) {
 | |
|                 var modeCreator = mode.createEncryptor;
 | |
|             } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
 | |
|                 var modeCreator = mode.createDecryptor;
 | |
| 
 | |
|                 // Keep at least one block in the buffer for unpadding
 | |
|                 this._minBufferSize = 1;
 | |
|             }
 | |
|             this._mode = modeCreator.call(mode, this, iv && iv.words);
 | |
|         },
 | |
| 
 | |
|         _doProcessBlock: function (words, offset) {
 | |
|             this._mode.processBlock(words, offset);
 | |
|         },
 | |
| 
 | |
|         _doFinalize: function () {
 | |
|             // Shortcut
 | |
|             var padding = this.cfg.padding;
 | |
| 
 | |
|             // Finalize
 | |
|             if (this._xformMode == this._ENC_XFORM_MODE) {
 | |
|                 // Pad data
 | |
|                 padding.pad(this._data, this.blockSize);
 | |
| 
 | |
|                 // Process final blocks
 | |
|                 var finalProcessedBlocks = this._process(!!'flush');
 | |
|             } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
 | |
|                 // Process final blocks
 | |
|                 var finalProcessedBlocks = this._process(!!'flush');
 | |
| 
 | |
|                 // Unpad data
 | |
|                 padding.unpad(finalProcessedBlocks);
 | |
|             }
 | |
| 
 | |
|             return finalProcessedBlocks;
 | |
|         },
 | |
| 
 | |
|         blockSize: 128/32
 | |
|     });
 | |
| 
 | |
|     /**
 | |
|      * A collection of cipher parameters.
 | |
|      *
 | |
|      * @property {WordArray} ciphertext The raw ciphertext.
 | |
|      * @property {WordArray} key The key to this ciphertext.
 | |
|      * @property {WordArray} iv The IV used in the ciphering operation.
 | |
|      * @property {WordArray} salt The salt used with a key derivation function.
 | |
|      * @property {Cipher} algorithm The cipher algorithm.
 | |
|      * @property {Mode} mode The block mode used in the ciphering operation.
 | |
|      * @property {Padding} padding The padding scheme used in the ciphering operation.
 | |
|      * @property {number} blockSize The block size of the cipher.
 | |
|      * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.
 | |
|      */
 | |
|     var CipherParams = C_lib.CipherParams = Base.extend({
 | |
|         /**
 | |
|          * Initializes a newly created cipher params object.
 | |
|          *
 | |
|          * @param {Object} cipherParams An object with any of the possible cipher parameters.
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var cipherParams = CryptoJS.lib.CipherParams.create({
 | |
|          *         ciphertext: ciphertextWordArray,
 | |
|          *         key: keyWordArray,
 | |
|          *         iv: ivWordArray,
 | |
|          *         salt: saltWordArray,
 | |
|          *         algorithm: CryptoJS.algo.AES,
 | |
|          *         mode: CryptoJS.mode.CBC,
 | |
|          *         padding: CryptoJS.pad.PKCS7,
 | |
|          *         blockSize: 4,
 | |
|          *         formatter: CryptoJS.format.OpenSSL
 | |
|          *     });
 | |
|          */
 | |
|         init: function (cipherParams) {
 | |
|             this.mixIn(cipherParams);
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Converts this cipher params object to a string.
 | |
|          *
 | |
|          * @param {Format} formatter (Optional) The formatting strategy to use.
 | |
|          *
 | |
|          * @return {string} The stringified cipher params.
 | |
|          *
 | |
|          * @throws Error If neither the formatter nor the default formatter is set.
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var string = cipherParams + '';
 | |
|          *     var string = cipherParams.toString();
 | |
|          *     var string = cipherParams.toString(CryptoJS.format.OpenSSL);
 | |
|          */
 | |
|         toString: function (formatter) {
 | |
|             return (formatter || this.formatter).stringify(this);
 | |
|         }
 | |
|     });
 | |
| 
 | |
|     /**
 | |
|      * Format namespace.
 | |
|      */
 | |
|     var C_format = C.format = {};
 | |
| 
 | |
|     /**
 | |
|      * OpenSSL formatting strategy.
 | |
|      */
 | |
|     var OpenSSLFormatter = C_format.OpenSSL = {
 | |
|         /**
 | |
|          * Converts a cipher params object to an OpenSSL-compatible string.
 | |
|          *
 | |
|          * @param {CipherParams} cipherParams The cipher params object.
 | |
|          *
 | |
|          * @return {string} The OpenSSL-compatible string.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);
 | |
|          */
 | |
|         stringify: function (cipherParams) {
 | |
|             // Shortcuts
 | |
|             var ciphertext = cipherParams.ciphertext;
 | |
|             var salt = cipherParams.salt;
 | |
| 
 | |
|             // Format
 | |
|             if (salt) {
 | |
|                 var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
 | |
|             } else {
 | |
|                 var wordArray = ciphertext;
 | |
|             }
 | |
| 
 | |
|             return wordArray.toString(Base64);
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Converts an OpenSSL-compatible string to a cipher params object.
 | |
|          *
 | |
|          * @param {string} openSSLStr The OpenSSL-compatible string.
 | |
|          *
 | |
|          * @return {CipherParams} The cipher params object.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);
 | |
|          */
 | |
|         parse: function (openSSLStr) {
 | |
|             // Parse base64
 | |
|             var ciphertext = Base64.parse(openSSLStr);
 | |
| 
 | |
|             // Shortcut
 | |
|             var ciphertextWords = ciphertext.words;
 | |
| 
 | |
|             // Test for salt
 | |
|             if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {
 | |
|                 // Extract salt
 | |
|                 var salt = WordArray.create(ciphertextWords.slice(2, 4));
 | |
| 
 | |
|                 // Remove salt from ciphertext
 | |
|                 ciphertextWords.splice(0, 4);
 | |
|                 ciphertext.sigBytes -= 16;
 | |
|             }
 | |
| 
 | |
|             return CipherParams.create({ ciphertext: ciphertext, salt: salt });
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     /**
 | |
|      * A cipher wrapper that returns ciphertext as a serializable cipher params object.
 | |
|      */
 | |
|     var SerializableCipher = C_lib.SerializableCipher = Base.extend({
 | |
|         /**
 | |
|          * Configuration options.
 | |
|          *
 | |
|          * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL
 | |
|          */
 | |
|         cfg: Base.extend({
 | |
|             format: OpenSSLFormatter
 | |
|         }),
 | |
| 
 | |
|         /**
 | |
|          * Encrypts a message.
 | |
|          *
 | |
|          * @param {Cipher} cipher The cipher algorithm to use.
 | |
|          * @param {WordArray|string} message The message to encrypt.
 | |
|          * @param {WordArray} key The key.
 | |
|          * @param {Object} cfg (Optional) The configuration options to use for this operation.
 | |
|          *
 | |
|          * @return {CipherParams} A cipher params object.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);
 | |
|          *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });
 | |
|          *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });
 | |
|          */
 | |
|         encrypt: function (cipher, message, key, cfg) {
 | |
|             // Apply config defaults
 | |
|             cfg = this.cfg.extend(cfg);
 | |
| 
 | |
|             // Encrypt
 | |
|             var encryptor = cipher.createEncryptor(key, cfg);
 | |
|             var ciphertext = encryptor.finalize(message);
 | |
| 
 | |
|             // Shortcut
 | |
|             var cipherCfg = encryptor.cfg;
 | |
| 
 | |
|             // Create and return serializable cipher params
 | |
|             return CipherParams.create({
 | |
|                 ciphertext: ciphertext,
 | |
|                 key: key,
 | |
|                 iv: cipherCfg.iv,
 | |
|                 algorithm: cipher,
 | |
|                 mode: cipherCfg.mode,
 | |
|                 padding: cipherCfg.padding,
 | |
|                 blockSize: cipher.blockSize,
 | |
|                 formatter: cfg.format
 | |
|             });
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Decrypts serialized ciphertext.
 | |
|          *
 | |
|          * @param {Cipher} cipher The cipher algorithm to use.
 | |
|          * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
 | |
|          * @param {WordArray} key The key.
 | |
|          * @param {Object} cfg (Optional) The configuration options to use for this operation.
 | |
|          *
 | |
|          * @return {WordArray} The plaintext.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });
 | |
|          *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });
 | |
|          */
 | |
|         decrypt: function (cipher, ciphertext, key, cfg) {
 | |
|             // Apply config defaults
 | |
|             cfg = this.cfg.extend(cfg);
 | |
| 
 | |
|             // Convert string to CipherParams
 | |
|             ciphertext = this._parse(ciphertext, cfg.format);
 | |
| 
 | |
|             // Decrypt
 | |
|             var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);
 | |
| 
 | |
|             return plaintext;
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Converts serialized ciphertext to CipherParams,
 | |
|          * else assumed CipherParams already and returns ciphertext unchanged.
 | |
|          *
 | |
|          * @param {CipherParams|string} ciphertext The ciphertext.
 | |
|          * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.
 | |
|          *
 | |
|          * @return {CipherParams} The unserialized ciphertext.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);
 | |
|          */
 | |
|         _parse: function (ciphertext, format) {
 | |
|             if (typeof ciphertext == 'string') {
 | |
|                 return format.parse(ciphertext, this);
 | |
|             } else {
 | |
|                 return ciphertext;
 | |
|             }
 | |
|         }
 | |
|     });
 | |
| 
 | |
|     /**
 | |
|      * Key derivation function namespace.
 | |
|      */
 | |
|     var C_kdf = C.kdf = {};
 | |
| 
 | |
|     /**
 | |
|      * OpenSSL key derivation function.
 | |
|      */
 | |
|     var OpenSSLKdf = C_kdf.OpenSSL = {
 | |
|         /**
 | |
|          * Derives a key and IV from a password.
 | |
|          *
 | |
|          * @param {string} password The password to derive from.
 | |
|          * @param {number} keySize The size in words of the key to generate.
 | |
|          * @param {number} ivSize The size in words of the IV to generate.
 | |
|          * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.
 | |
|          *
 | |
|          * @return {CipherParams} A cipher params object with the key, IV, and salt.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);
 | |
|          *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');
 | |
|          */
 | |
|         execute: function (password, keySize, ivSize, salt) {
 | |
|             // Generate random salt
 | |
|             if (!salt) {
 | |
|                 salt = WordArray.random(64/8);
 | |
|             }
 | |
| 
 | |
|             // Derive key and IV
 | |
|             var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
 | |
| 
 | |
|             // Separate key and IV
 | |
|             var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);
 | |
|             key.sigBytes = keySize * 4;
 | |
| 
 | |
|             // Return params
 | |
|             return CipherParams.create({ key: key, iv: iv, salt: salt });
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     /**
 | |
|      * A serializable cipher wrapper that derives the key from a password,
 | |
|      * and returns ciphertext as a serializable cipher params object.
 | |
|      */
 | |
|     var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({
 | |
|         /**
 | |
|          * Configuration options.
 | |
|          *
 | |
|          * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL
 | |
|          */
 | |
|         cfg: SerializableCipher.cfg.extend({
 | |
|             kdf: OpenSSLKdf
 | |
|         }),
 | |
| 
 | |
|         /**
 | |
|          * Encrypts a message using a password.
 | |
|          *
 | |
|          * @param {Cipher} cipher The cipher algorithm to use.
 | |
|          * @param {WordArray|string} message The message to encrypt.
 | |
|          * @param {string} password The password.
 | |
|          * @param {Object} cfg (Optional) The configuration options to use for this operation.
 | |
|          *
 | |
|          * @return {CipherParams} A cipher params object.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');
 | |
|          *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });
 | |
|          */
 | |
|         encrypt: function (cipher, message, password, cfg) {
 | |
|             // Apply config defaults
 | |
|             cfg = this.cfg.extend(cfg);
 | |
| 
 | |
|             // Derive key and other params
 | |
|             var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);
 | |
| 
 | |
|             // Add IV to config
 | |
|             cfg.iv = derivedParams.iv;
 | |
| 
 | |
|             // Encrypt
 | |
|             var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);
 | |
| 
 | |
|             // Mix in derived params
 | |
|             ciphertext.mixIn(derivedParams);
 | |
| 
 | |
|             return ciphertext;
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * Decrypts serialized ciphertext using a password.
 | |
|          *
 | |
|          * @param {Cipher} cipher The cipher algorithm to use.
 | |
|          * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
 | |
|          * @param {string} password The password.
 | |
|          * @param {Object} cfg (Optional) The configuration options to use for this operation.
 | |
|          *
 | |
|          * @return {WordArray} The plaintext.
 | |
|          *
 | |
|          * @static
 | |
|          *
 | |
|          * @example
 | |
|          *
 | |
|          *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });
 | |
|          *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });
 | |
|          */
 | |
|         decrypt: function (cipher, ciphertext, password, cfg) {
 | |
|             // Apply config defaults
 | |
|             cfg = this.cfg.extend(cfg);
 | |
| 
 | |
|             // Convert string to CipherParams
 | |
|             ciphertext = this._parse(ciphertext, cfg.format);
 | |
| 
 | |
|             // Derive key and other params
 | |
|             var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);
 | |
| 
 | |
|             // Add IV to config
 | |
|             cfg.iv = derivedParams.iv;
 | |
| 
 | |
|             // Decrypt
 | |
|             var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);
 | |
| 
 | |
|             return plaintext;
 | |
|         }
 | |
|     });
 | |
| }());
 |