【问题标题】:how to do the same Nodejs crypto aes encryption CTR in PHP7?如何在 PHP7 中做同样的 Nodejs 加密 aes 加密 CTR?
【发布时间】:2020-06-26 04:29:55
【问题描述】:

这是我从互联网上获取的nodejs代码。

// Nodejs encryption with CTR
var crypto = require('crypto'),
    algorithm = 'aes-128-ofb',
    password = 'password12';

function encrypt(text){
  var cipher = crypto.createCipher(algorithm,password)
  var crypted = cipher.update(text,'utf8','hex')
  crypted += cipher.final('hex');
  return crypted;
}

function decrypt(text){
  var decipher = crypto.createDecipher(algorithm,password)
  var dec = decipher.update(text,'hex','utf8')
  dec += decipher.final('utf8');
  return dec;
}

var hw = encrypt("hello world")
// outputs hello world
console.log(decrypt(hw));

它工作正常
但是当我尝试在 php7 中使用 openssl_decrypt 解密它时,我得到了错误/不同的结果。
有人可以帮忙吗?

【问题讨论】:

  • 你能添加你的php代码进行解密吗?
  • 有一些库。 This 就是其中之一。
  • @Pete 是的,我正在尝试使用 openssl_decrypt OPENSSL_RAW_DATA 它返回凹凸随机符号..
  • @DavidJawHpan 好的,我会试一试
  • NodeJS代码可以修改吗? crypto.createCipher 已被弃用,并且还使用非标准(而且不是很安全)KDF 来派生密钥和 IV,这必须在 PHP 代码中实现(不过这不会很复杂)。因此,如果可以切换到crypto.createCipheriv,则应该这样做。这更安全,并且可以在此处直接指定密钥和 IV(或通过 reliable KDF 派生)。此外,移植到 PHP 更容易。此外,标题和发布的代码在模式(CTR vs OFB)方面是矛盾的。究竟是什么模式?

标签: php html node.js encryption aes


【解决方案1】:

PHP 代码没有给出您期望的答案的原因是 crypto.createCipher 使用另一个函数从提供的密码派生密钥和初始化向量 (iv)。

有问题的函数是EVP_BytesToKey

以下是用于解密您的密文的 PHP 代码。我还包含了一个加密函数,因此您可以在 PHP 中以相同的方式进行加密。

function EVP_BytesToKey($data, $count, $cipher, $hashMethod) {
    $iv_length  = openssl_cipher_iv_length($cipher);
    $key_length = $iv_length; // This assumption may not always be true...
    $result = "";
    $digestInput = "";
    while(strlen($result) < ($key_length + $iv_length)) {
        $digestInput .= $data;
        $digest = openssl_digest($digestInput, $hashMethod);
        for ($iteration = 1; $iteration < $count; $iteration++) {
            $digest = openssl_digest(hex2bin($digest), $hashMethod);
        }
        $digestInput = hex2bin($digest);
        $result .= hex2bin($digest);
    }
    return (object)["key" => substr($result, 0, $key_length), "iv" => substr($result, $key_length, $iv_length)];
}

function decrypt($encryptedHex, $cipher, $password) {
    $encrypted = hex2bin($encryptedHex);
    $evp = EVP_BytesToKey($password, 1, $cipher, "md5");
    return openssl_decrypt($encrypted, $cipher, $evp->key, OPENSSL_RAW_DATA, $evp->iv);
}

function encrypt($plainText, $cipher, $password) {
    $evp = EVP_BytesToKey($password, 1, $cipher, "md5");
    return bin2hex(openssl_encrypt($plainText, $cipher, $evp->key, OPENSSL_RAW_DATA, $evp->iv));
}

$algorithm = "aes-128-ofb";
$password = "password12";
$encryptedHex = "f2211645785e4232339a0d";

echo "Ciphertext (hex): " . $encryptedHex . "\n";
echo "Plaintext: " . decrypt($encryptedHex, $algorithm, $password);

【讨论】:

    猜你喜欢
    • 2015-06-09
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    相关资源
    最近更新 更多