javascript - CryptoJS 和 openssl_decrypt 不会产生相同的结果

标签 javascript php encryption cryptojs php-openssl

我正在尝试在 php 和 JavaScript 上使用字符串实现 AES 256 位加密。对于 jasvascript,我思考 CryptoJS 和 php,我使用 openssl_decrypt/enecrypt。

下面是加密和解密的JS代码。

JavaScript

function aes_encrypt(str_to_encrypt){
  if(str_to_encrypt==null)
   return "";

   var key = CryptoJS.enc.Hex.parse("0123456789abcdef0123456789abcdef");
   var iv = CryptoJS.enc.Hex.parse("abcdef9876543210abcdef9876543210");


  var encrypted = CryptoJS.AES.encrypt(str_to_encrypt,key, {'mode': CryptoJS.mode.CBC, iv: iv});
  var encryptedString = encrypted.toString();
  return  encryptedString;
}

function aes_decrypt(str_to_decrypt){
  if(str_to_decrypt==null)
   return "";

   var key = CryptoJS.enc.Hex.parse("0123456789abcdef0123456789abcdef");
   var iv = CryptoJS.enc.Hex.parse("abcdef9876543210abcdef9876543210");

  var decrypted = CryptoJS.AES.decrypt(str_to_decrypt,key, {'mode': CryptoJS.mode.CBC, iv: iv });
  var decryptedString = decrypted.toString(CryptoJS.enc.Utf8);
  return decryptedString;
}

在 php 中,代码是

PHP

class Crypto_AES256
{
  public $key = "0123456789abcdef0123456789abcdef";
  public $iv =  "abcdef9876543210abcdef9876543210";


  public  $encrypt_method = 'AES-256-CBC';

  function __construct ()
  {
     $this->key = hex2bin($this->key);
     $this->iv = hex2bin($this->iv);
    
  }

  public function encrypt ( $string )
  {
    if ( $encrypted = base64_encode( openssl_encrypt ( $string, $this->encrypt_method, $this->key, 0, $this->iv ) ) )
    {
      return $encrypted;
    }
    else
    {
      return false;
    }
  }
  public function decrypt ($string)
  {

    if ( $decrypted = openssl_decrypt ( base64_decode ( $string ), $this->encrypt_method, $this->key, 0, $this->iv ) )
    {
      return $decrypted;
    }
    else
    {
      return false;
    }
  }
}

但是JavaScript端的加密结果与php不一样,我需要在JavaScript和php上产生相同的加密和加密结果。可能是什么问题。

最佳答案

这两个代码有两个不同之处:

  • PHP 代码应用 AES-256,但由于仅使用 16 字节 key (由于十六进制解码),PHP 会自动用 0 值将其填充到 32 字节的长度。在CryptoJS代码中, key 长度决定模式,因此应用AES-128。为了使两个代码产生相同的结果,必须在 CryptoJS 代码中像 PHP 代码一样扩展 key ,或者必须在 PHP 代码中使用 AES-128。
  • 在 PHP 代码中,openssl_encrypt() 默认返回 Base64 编码的密文,因此密文目前经过 Base64 编码两次。因此,删除显式的 base64_encode() 或使用 OPENSSL_RAW_DATA 作为第四个参数,以便返回原始数据。 openssl_decrypt() 也类似。

当这些问题得到解决后,这两个代码在我的机器上提供相同的密文。请注意,静态 IV 是不安全的(另请参阅评论),但您可能仅出于测试目的才这样做。


示例:以下代码使用未修改的 CryptoJS 代码,即 AES-128:

function aes_encrypt(str_to_encrypt){
    if(str_to_encrypt==null)
        return "";

    var key = CryptoJS.enc.Hex.parse("0123456789abcdef0123456789abcdef");
    var iv = CryptoJS.enc.Hex.parse("abcdef9876543210abcdef9876543210");

    var encrypted = CryptoJS.AES.encrypt(str_to_encrypt,key, {'mode': CryptoJS.mode.CBC, iv: iv});
    var encryptedString = encrypted.toString();
    return  encryptedString;
}

function aes_decrypt(str_to_decrypt){
    if(str_to_decrypt==null)
        return "";

    var key = CryptoJS.enc.Hex.parse("0123456789abcdef0123456789abcdef");
    var iv = CryptoJS.enc.Hex.parse("abcdef9876543210abcdef9876543210");

    var decrypted = CryptoJS.AES.decrypt(str_to_decrypt,key, {'mode': CryptoJS.mode.CBC, iv: iv });
    var decryptedString = decrypted.toString(CryptoJS.enc.Utf8);
    return decryptedString;
}

var ciphertext = aes_encrypt('The quick brown fox jumps over the lazy dog');
var decrypted = aes_decrypt(ciphertext);
console.log(ciphertext.replace(/(.{56})/g,'$1\n'));
console.log(decrypted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

如果应用 AES-128-CBC 并且将 OPENSSL_RAW_DATA 标志设置为 openssl_encrypt() 中的第四个参数,则 PHP 代码返回相同的密文>openssl_decrypt().

关于javascript - CryptoJS 和 openssl_decrypt 不会产生相同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66125866/

相关文章:

PHP * 小时前

python - Python中GCM模式下的AES

c - 使用 Openssl EVP 库加密和使用 openssl enc 终端命令解密失败

java - 如何修复 “Incorrect string value for the column at the row 1”错误?

javascript - 如何将一个表中一行的内容复制到另一个表中并添加相同的行

javascript - Webkit JavaScript 引用

php - 具有循环引用的对象上的 in_array

php - 抽象类的目的是什么?

javascript - onClick 调度一个操作。我如何等待我的派送完成?

javascript - 正则表达式多次替换组