【问题标题】:AES Encryption in PHP and Decryption in JavascriptPHP中的AES加密和Javascript中的解密
【发布时间】:2021-04-13 05:39:25
【问题描述】:

我有一个应用程序,我在其中使用 AES CBC 128 算法加密一个 json 编码数组,然后在 javascript(React/Next Js 项目)中解密它。我在php中的加密如下代码所示

加密 PHP


$plaintext = "message to be encrypted";
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
$ciphertext = base64_encode( $iv.$hmac.$ciphertext_raw );

我在用 Javascript 解密时遇到问题

到目前为止我的代码如下所示

 const baseenc = CryptoJS.enc.Base64.parse(cipher).toString();
  var encrypted = CryptoJS.AES.decrypt(cipher, key, { iv: iv }).toString();
  var plaintext = CryptoJS.enc.Latin1.stringify(encrypted);

请任何机构显示错误是什么或帮助我获得正确的输出

【问题讨论】:

  • 您的 CryptoJS 代码缺少 IV、HMAC 和实际密文的分离。此外,必须计算密文的 HMAC。如果计算和接收到的 HMAC 匹配,则密文是真实的。认证成功后,您需要 IV 和密钥来解密实际密文。另请参阅here,了解使用相同的密钥进行加密和身份验证。
  • @Topaco 那么你能帮我吗?我怎样才能分离 iv hmac 和密文
  • 好的,请看我的回答。

标签: javascript php encryption aes


【解决方案1】:

必须在 CryptoJS 代码中实现以下步骤:

  • 分离 IV、HMAC 和密文(经过 Base64 解码)
  • 计算密文的 HMAC
  • 检查密文的真实性。如果接收和计算的 HMAC 相同,则密文是真实的。
  • 仅当密文是真实的时才执行解密

以下代码是一个可能的实现。由于应用了密钥 0123456789012345,并使用 PHP 代码生成了使用的密文:

var ciphertext = 'WqfMfCxKg7U7h5S1mbx7mSHOkkkIrUUpg++mX4ZdWt0I26VfKn7bsi60Oo/SIsWQGyC4dF5z081NvjTXwZGjIpguA0k/QqIM/GDEpCojaro=';
var key = '0123456789012345';

// Convert key and ciphertext into WordArrays
var ciphertextWA = CryptoJS.enc.Base64.parse(ciphertext);
var keyWA = CryptoJS.enc.Utf8.parse(key);

// Separate IV, HMAC and ciphertext
var ivWA = CryptoJS.lib.WordArray.create(ciphertextWA.words.slice(0, 4)); 
var hmacWA = CryptoJS.lib.WordArray.create(ciphertextWA.words.slice(4, 4 + 8)); 
var actualCiphertextWA = CryptoJS.lib.WordArray.create(ciphertextWA.words.slice(4 + 8)); 

// Authenticate
var hmacCalculatedWA = CryptoJS.HmacSHA256(actualCiphertextWA, keyWA); 
if(CryptoJS.enc.Base64.stringify(hmacCalculatedWA) === CryptoJS.enc.Base64.stringify(hmacWA)) {
  
  // Decrypt if authentication is successfull
  var decryptedMessageWA = CryptoJS.AES.decrypt({ciphertext: actualCiphertextWA}, keyWA, {iv: ivWA});
  var decryptedMessage = CryptoJS.enc.Utf8.stringify(decryptedMessageWA);
  console.log(decryptedMessage);
} else {
  console.log('Authentication failed!');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

请注意最好使用不同的密钥进行加密和身份验证,请参阅here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-17
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多