JavaScript 使用CryptoJS实现AES-256-CBC加密/解密函数

时间:2022-06-01 17:44:17

AES-256-CBC的加解密函数使用的是crypto-js.js来实现,crypto-js.js下载地址是https://github.com/brix/crypto-js/releases crypto-js.js。

实现AES-256-CBC加解密代码

/**
* Encryption class for encrypt/decrypt that works between programming languages.
*
* @author Vee Winch.
* @link https://*.com/questions/41222162/encrypt-in-php-openssl-and-decrypt-in-javascript-cryptojs Reference.
* @link https://github.com/brix/crypto-js/releases crypto-js.js can be download from here.
*/
class Encryption {
/**
* @var integer Return encrypt method or Cipher method number. (128, 192, 256)
*/
get encryptMethodLength() {
var encryptMethod = this.encryptMethod;
// get only number from string.
// @link https://*.com/a/10003709/128761 Reference.
var aesNumber = encryptMethod.match(/\d+/)[0];
return parseInt(aesNumber);
}// encryptMethodLength

/**
* @var integer Return cipher method divide by 8. example: AES number 256 will be 256/8 = 32.
*/
get encryptKeySize() {
var aesNumber = this.encryptMethodLength;
return parseInt(aesNumber / 8);
}// encryptKeySize

/**
* @link http://php.net/manual/en/function.openssl-get-cipher-methods.php Refer to available methods in PHP if we are working between JS & PHP encryption.
* @var string Cipher method.
* Recommended AES-128-CBC, AES-192-CBC, AES-256-CBC
* due to there is no `openssl_cipher_iv_length()` function in JavaScript
* and all of these methods are known as 16 in iv_length.
*/
get encryptMethod() {
return 'AES-256-CBC';
}// encryptMethod

/**
* Decrypt string.
*
* @link https://*.com/questions/41222162/encrypt-in-php-openssl-and-decrypt-in-javascript-cryptojs Reference.
* @link https://*.com/questions/25492179/decode-a-base64-string-using-cryptojs Crypto JS base64 encode/decode reference.
* @param string encryptedString The encrypted string to be decrypt.
* @param string key The key.
* @return string Return decrypted string.
*/
decrypt(encryptedString, key) {
var json = JSON.parse(CryptoJS.enc.Utf8.stringify(CryptoJS.enc.Base64.parse(encryptedString)));
var salt = CryptoJS.enc.Hex.parse(json.salt);
var iv = CryptoJS.enc.Hex.parse(json.iv);
var encrypted = json.ciphertext;// no need to base64 decode.
var iterations = parseInt(json.iterations);
if (iterations <= 0) {
iterations = 999;
}
var encryptMethodLength = (this.encryptMethodLength/4);// example: AES number is 256 / 4 = 64
var hashKey = CryptoJS.PBKDF2(key, salt, {'hasher': CryptoJS.algo.SHA512, 'keySize': (encryptMethodLength/8), 'iterations': iterations});
var decrypted = CryptoJS.AES.decrypt(encrypted, hashKey, {'mode': CryptoJS.mode.CBC, 'iv': iv});
return decrypted.toString(CryptoJS.enc.Utf8);
}// decrypt

/**
* Encrypt string.
*
* @link https://*.com/questions/41222162/encrypt-in-php-openssl-and-decrypt-in-javascript-cryptojs Reference.
* @link https://*.com/questions/25492179/decode-a-base64-string-using-cryptojs Crypto JS base64 encode/decode reference.
* @param string string The original string to be encrypt.
* @param string key The key.
* @return string Return encrypted string.
*/
encrypt(string, key) {
var iv = CryptoJS.lib.WordArray.random(16);// the reason to be 16, please read on `encryptMethod` property.
var salt = CryptoJS.lib.WordArray.random(256);
var iterations = 999;
var encryptMethodLength = (this.encryptMethodLength/4);// example: AES number is 256 / 4 = 64
var hashKey = CryptoJS.PBKDF2(key, salt, {'hasher': CryptoJS.algo.SHA512, 'keySize': (encryptMethodLength/8), 'iterations': iterations});
var encrypted = CryptoJS.AES.encrypt(string, hashKey, {'mode': CryptoJS.mode.CBC, 'iv': iv});
var encryptedString = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
var output = {
'ciphertext': encryptedString,
'iv': CryptoJS.enc.Hex.stringify(iv),
'salt': CryptoJS.enc.Hex.stringify(salt),
'iterations': iterations
};
return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(JSON.stringify(output)));
}// encrypt
}