使用 CryptoJS 和 PHP 的 AES 加密
AES Encryption with CryptoJS and PHP
我想使用 JavaScript 实现 AES 加密。使用 AES CBC 模式。我已经在 PHP 中做到了。看起来像:
public function encrypt($value) {
if (empty($value)) {
return $value;
}
$value = Unicode::convertToUtf8($value, 'UTF-8');
if ($key = $this->getEncryptionKey()) {
// Generates from key 1st 16 bytes.
$iv = mb_substr($key, 0, 16);
//encrypt message with key
$message = openssl_encrypt($value, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($message);
}
}
public function getEncryptionKey() {
$key = 'secret';
$key = Unicode::convertToUtf8($key, 'UTF-8');
// Make sure the key is the correct size.
if (strlen($key) < 32) {
$key = str_pad($key, 32, "[=11=]");
}
if (strlen($key) > 32) {
$key = mb_substr($key, 0, 32);
}
return $key;
}
如果我给$value = retest2;它给了我 ukUCH0SvgdmM8vTqQumAVg== 输出
我知道这是对的,我用 C# 试过,也得到了同样的结果。但是当我尝试使用 JavaScript 复制它时,我无法生成相同的 PHP 的输出。下面是我试过的 javascript 代码:
const message = utf8.encode('retest2');
const password = utf8.encode('secret').padEnd(32, '[=12=]');
const key = CryptoJS.enc.Hex.parse(password);
const iv = CryptoJS.enc.Hex.parse(password.substring(0, 16));
const encrypted = CryptoJS.AES.encrypt(message, key, {
iv: iv
});
console.log(btoa(encrypted.toString()));
使用相同的值我得到 dzd4bjNwenduQT09。
我在这里也阅读了关于同一主题的其他类似问题,但我似乎无法弄清楚我哪里出错了?
谢谢!
这些应该是评论,但 space 是有限的....
您不应使用密钥或从中派生的数据作为初始化向量。
I know it's right, I tried it using C# as well
您应该已经向我们展示了代码。
您的 openssl 调用调用 key derivation function to create a (better?) encryption key from the data you pass in the third parameter. OTOH, in crypto.js there is no implicit key derivation.
正如@symcbean 所说,
You shouldn't be using the key or data derived from it as your
initialization vector.
我假设,你别无选择,你必须使用密钥或从中派生的数据作为你的初始化向量。
几个月前,我遇到了完全相同的情况,我做了这样的事情,
const message = 'retest2';
let password = 'secret';
if (password.length < 32) {
password = password.padEnd(32, '[=10=]');
}
const iv = CryptoJS.enc.Utf8.parse(password.substring(0, 16));
password = CryptoJS.enc.Utf8.parse(password);
const encrypted = CryptoJS.AES.encrypt((message), (password), {
iv: iv
});
console.log(CryptoJS.enc.Base64.stringify(encrypted.ciphertext));
我想使用 JavaScript 实现 AES 加密。使用 AES CBC 模式。我已经在 PHP 中做到了。看起来像:
public function encrypt($value) {
if (empty($value)) {
return $value;
}
$value = Unicode::convertToUtf8($value, 'UTF-8');
if ($key = $this->getEncryptionKey()) {
// Generates from key 1st 16 bytes.
$iv = mb_substr($key, 0, 16);
//encrypt message with key
$message = openssl_encrypt($value, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($message);
}
}
public function getEncryptionKey() {
$key = 'secret';
$key = Unicode::convertToUtf8($key, 'UTF-8');
// Make sure the key is the correct size.
if (strlen($key) < 32) {
$key = str_pad($key, 32, "[=11=]");
}
if (strlen($key) > 32) {
$key = mb_substr($key, 0, 32);
}
return $key;
}
如果我给$value = retest2;它给了我 ukUCH0SvgdmM8vTqQumAVg== 输出
我知道这是对的,我用 C# 试过,也得到了同样的结果。但是当我尝试使用 JavaScript 复制它时,我无法生成相同的 PHP 的输出。下面是我试过的 javascript 代码:
const message = utf8.encode('retest2');
const password = utf8.encode('secret').padEnd(32, '[=12=]');
const key = CryptoJS.enc.Hex.parse(password);
const iv = CryptoJS.enc.Hex.parse(password.substring(0, 16));
const encrypted = CryptoJS.AES.encrypt(message, key, {
iv: iv
});
console.log(btoa(encrypted.toString()));
使用相同的值我得到 dzd4bjNwenduQT09。 我在这里也阅读了关于同一主题的其他类似问题,但我似乎无法弄清楚我哪里出错了? 谢谢!
这些应该是评论,但 space 是有限的....
您不应使用密钥或从中派生的数据作为初始化向量。
I know it's right, I tried it using C# as well
您应该已经向我们展示了代码。
您的 openssl 调用调用 key derivation function to create a (better?) encryption key from the data you pass in the third parameter. OTOH, in crypto.js there is no implicit key derivation.
正如@symcbean 所说,
You shouldn't be using the key or data derived from it as your initialization vector.
我假设,你别无选择,你必须使用密钥或从中派生的数据作为你的初始化向量。
几个月前,我遇到了完全相同的情况,我做了这样的事情,
const message = 'retest2';
let password = 'secret';
if (password.length < 32) {
password = password.padEnd(32, '[=10=]');
}
const iv = CryptoJS.enc.Utf8.parse(password.substring(0, 16));
password = CryptoJS.enc.Utf8.parse(password);
const encrypted = CryptoJS.AES.encrypt((message), (password), {
iv: iv
});
console.log(CryptoJS.enc.Base64.stringify(encrypted.ciphertext));