CryptoJS 提供了非常方便的加密接口 CryptoJS.AES.encrypt
和解密接口 CryptoJS.AES.decrypt
,但是这两个接口对于其他语言来说就非常不友好。比如 PHP 就不能直接使用 openssl 的组件来加解密,好在 PHP 已有人给出解决办法。
Node.js 要使用也比较简单,直接引入 CryptoJS 就可以开始使用,其他语言也应该有人提供了解决办法。
class CryptoJS
{
static public function aesEncrypt($data, $key)
{
$salted = 'Salted__';
$salt = openssl_random_pseudo_bytes(8);
$config = self::generateKey($key, $salt);
$encrypt = openssl_encrypt(
$data,
'AES-256-CBC',
$config['key'],
OPENSSL_RAW_DATA, // base64 was already decoded
$config['iv']
);
return base64_encode($salted . $salt . $encrypt);
}
static public function aesDecrypt($data, $key)
{
$data = base64_decode($data);
if (substr($data, 0, 8) != 'Salted__') {
return false;
}
$salt = substr($data, 8, 8);
$config = self::generateKey($key, $salt);
return openssl_decrypt(
substr($data, 16),
'AES-256-CBC',
$config['key'],
OPENSSL_RAW_DATA, // base64 was already decoded
$config['iv']
);
}
static protected function generateKey(
$password,
$salt,
$keySize = 8,
$ivSize = 4,
$iterations = 1,
$hashAlgorithm = 'md5'
)
{
$targetKeySize = $keySize + $ivSize;
$derivedBytes = '';
$numberOfDerivedWords = 0;
$block = null;
$hasher = hash_init($hashAlgorithm);
while ($numberOfDerivedWords < $targetKeySize) {
if ($block != null) {
hash_update($hasher, $block);
}
hash_update($hasher, $password);
hash_update($hasher, $salt);
$block = hash_final($hasher, true);
$hasher = hash_init($hashAlgorithm);
// Iterations
for ($i = 1; $i < $iterations; $i++) {
hash_update($hasher, $block);
$block = hash_final($hasher, true);
$hasher = hash_init($hashAlgorithm);
}
$derivedBytes .= substr(
$block,
0,
min(strlen($block), ($targetKeySize - $numberOfDerivedWords) * 4)
);
$numberOfDerivedWords += strlen($block) / 4;
}
return [
'key' => substr($derivedBytes, 0, $keySize * 4),
'iv' => substr($derivedBytes, $keySize * 4, $ivSize * 4),
];
}
}
来源:Encrypt with PHP, Decrypt with Javascript (cryptojs) - Stack Overflow