как сделать такой же Nodejs шифрование CTR шифрования в PHP7? - PullRequest
0 голосов
/ 14 марта 2020

так вот код nodejs, который я взял из inte rnet.

// 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));

, он работает нормально
, но когда я пытаюсь расшифровать его с помощью openssl_decrypt в php7 Я ошибся / другой результат.
может кто-нибудь помочь?

1 Ответ

0 голосов
/ 14 марта 2020

Причина, по которой код 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);
...