895 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
		
			
		
	
	
			895 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
|  | ;(function (root, factory, undef) { | ||
|  | 	if (typeof exports === "object") { | ||
|  | 		// CommonJS
 | ||
|  | 		module.exports = exports = factory(require("./core"), require("./evpkdf")); | ||
|  | 	} | ||
|  | 	else if (typeof define === "function" && define.amd) { | ||
|  | 		// AMD
 | ||
|  | 		define(["./core", "./evpkdf"], factory); | ||
|  | 	} | ||
|  | 	else { | ||
|  | 		// Global (browser)
 | ||
|  | 		factory(root.CryptoJS); | ||
|  | 	} | ||
|  | }(this, function (CryptoJS) { | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * 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) { | ||
|  | 	            var block; | ||
|  | 
 | ||
|  | 	            // Shortcut
 | ||
|  | 	            var iv = this._iv; | ||
|  | 
 | ||
|  | 	            // Choose mixing block
 | ||
|  | 	            if (iv) { | ||
|  | 	                block = iv; | ||
|  | 
 | ||
|  | 	                // Remove IV for subsequent blocks
 | ||
|  | 	                this._iv = undefined; | ||
|  | 	            } else { | ||
|  | 	                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 () { | ||
|  | 	            var modeCreator; | ||
|  | 
 | ||
|  | 	            // 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) { | ||
|  | 	                modeCreator = mode.createEncryptor; | ||
|  | 	            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { | ||
|  | 	                modeCreator = mode.createDecryptor; | ||
|  | 	                // Keep at least one block in the buffer for unpadding
 | ||
|  | 	                this._minBufferSize = 1; | ||
|  | 	            } | ||
|  | 
 | ||
|  | 	            if (this._mode && this._mode.__creator == modeCreator) { | ||
|  | 	                this._mode.init(this, iv && iv.words); | ||
|  | 	            } else { | ||
|  | 	                this._mode = modeCreator.call(mode, this, iv && iv.words); | ||
|  | 	                this._mode.__creator = modeCreator; | ||
|  | 	            } | ||
|  | 	        }, | ||
|  | 
 | ||
|  | 	        _doProcessBlock: function (words, offset) { | ||
|  | 	            this._mode.processBlock(words, offset); | ||
|  | 	        }, | ||
|  | 
 | ||
|  | 	        _doFinalize: function () { | ||
|  | 	            var finalProcessedBlocks; | ||
|  | 
 | ||
|  | 	            // 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
 | ||
|  | 	                finalProcessedBlocks = this._process(!!'flush'); | ||
|  | 	            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { | ||
|  | 	                // Process final blocks
 | ||
|  | 	                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) { | ||
|  | 	            var wordArray; | ||
|  | 
 | ||
|  | 	            // Shortcuts
 | ||
|  | 	            var ciphertext = cipherParams.ciphertext; | ||
|  | 	            var salt = cipherParams.salt; | ||
|  | 
 | ||
|  | 	            // Format
 | ||
|  | 	            if (salt) { | ||
|  | 	                wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext); | ||
|  | 	            } else { | ||
|  | 	                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) { | ||
|  | 	            var salt; | ||
|  | 
 | ||
|  | 	            // Parse base64
 | ||
|  | 	            var ciphertext = Base64.parse(openSSLStr); | ||
|  | 
 | ||
|  | 	            // Shortcut
 | ||
|  | 	            var ciphertextWords = ciphertext.words; | ||
|  | 
 | ||
|  | 	            // Test for salt
 | ||
|  | 	            if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) { | ||
|  | 	                // Extract salt
 | ||
|  | 	                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, hasher) { | ||
|  | 	            // Generate random salt
 | ||
|  | 	            if (!salt) { | ||
|  | 	                salt = WordArray.random(64/8); | ||
|  | 	            } | ||
|  | 
 | ||
|  | 	            // Derive key and IV
 | ||
|  | 	            if (!hasher) { | ||
|  | 	                var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); | ||
|  | 	            } else { | ||
|  | 	                var key = EvpKDF.create({ keySize: keySize + ivSize, hasher: hasher }).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, cfg.salt, cfg.hasher); | ||
|  | 
 | ||
|  | 	            // 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, cfg.hasher); | ||
|  | 
 | ||
|  | 	            // Add IV to config
 | ||
|  | 	            cfg.iv = derivedParams.iv; | ||
|  | 
 | ||
|  | 	            // Decrypt
 | ||
|  | 	            var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg); | ||
|  | 
 | ||
|  | 	            return plaintext; | ||
|  | 	        } | ||
|  | 	    }); | ||
|  | 	}()); | ||
|  | 
 | ||
|  | 
 | ||
|  | })); |