2017-02-22 20 views
3

Я обновил мою версию php до 7.1. У меня были функции, где я шифровал данные с помощью mcrypt. Теперь эта функция устарела.Как дешифровать после стирания Mcrypt?

Как я могу расшифровать данные в любом случае с возвратом к старым версиям php.

Это код, который я использовал:

public function encrypt($plaintext) { 
    $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); 
    $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM); 
    $ciphertext = mcrypt_encrypt(self::CIPHER, $this->key, $plaintext, self::MODE, $iv); 
    return base64_encode($iv.$ciphertext); 
} 

public function decrypt($ciphertext) { 
    $ciphertext = base64_decode($ciphertext); 
    $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); 
    if (strlen($ciphertext) < $ivSize) { 
     throw new Exception('Missing initialization vector'); 
    } 

    $iv = substr($ciphertext, 0, $ivSize); 
    $ciphertext = substr($ciphertext, $ivSize); 
    $plaintext = mcrypt_decrypt(self::CIPHER, $this->key, $ciphertext, self::MODE, $iv); 
    return rtrim($plaintext, "\0"); 
} 

С Константы:

const CIPHER = MCRYPT_RIJNDAEL_128; // Rijndael-128 is AES 
const MODE = MCRYPT_MODE_CBC; 

я увидел, что это было рекомендовано использовать OpenSSL. Это то, что я буду использовать с этого момента. Но как я могу расшифровать старые данные с помощью этого метода?

Благодаря

Edit: Я знаю, что я могу использовать OpenSSL в качестве альтернативы. То, что я делаю для контента с этого момента. Но мне нужно расшифровать мой сшитый код из моего старого содержимого.

* Редактировать запрос @symcbean

Пробовал расшифровать с помощью OpenSSL, как это:

public function decrypt($ciphertext) { 
    $ciphertext = base64_decode($ciphertext); 

    if (!function_exists("openssl_decrypt")) { 
     throw new Exception("aesDecrypt needs openssl php module."); 
    } 

$key = $this->key; 
$method = 'AES-256-CBC'; 
$ivSize = openssl_cipher_iv_length($method); 
$iv  = substr($ciphertext,0,$ivSize); 
$data = substr($ciphertext,$ivSize); 
$clear = openssl_decrypt ($data, $method, $key, 'OPENSSL_RAW_DATA'|'OPENSSL_ZERO_PADDING', $iv); 

return $clear; 
} 
+0

Возможный дубликат [PHP 7 - mcrypt устарел, нужна альтернатива] (http://stackoverflow.com/questions/41272257/php-7-mcrypt-deprecated-need-alternative) – Ben

+0

Его нет. Мне не нужна альтернатива. Я знаю, что могу использовать openssl. Но мне нужно расшифровать мой mcrypted контент. –

+3

@Ben: не согласен - это обсуждение паролей, и принятый ответ не касается конкретной проблемы дешифрования. – symcbean

ответ

0

я решил. Не знаю, правильно ли это (0) Но подключен удаленно на сервере с более низкой версией php. Расшифровано все содержимое и зашифровано с помощью OpenSSL.

Спасибо за предложения!

1

Важно отметить, что mcrypt_encrypt нулевой колодки входные данные, если это не кратен размера блока. Это приводит к неоднозначным результатам, если сами данные имеют завершающие нули.

openssl_decrypt не удаляет нулевое заполнение автоматически, поэтому вы остаетесь только с возможностью обрезки конечных нулей.

Вот тривиальный пример:

$data = "Lorem ipsum"; 
$key = "1234567890abcdef"; 
$iv = "1234567890abcdef"; 

$encrypted = mcrypt_encrypt(
    MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv); 
echo bin2hex($encrypted) . "\n"; 

$decrypted = openssl_decrypt(
    $encrypted, "AES-128-CBC", $key, 
    OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); 
echo var_export($decrypted, true) . "\n"; 
$result = rtrim($decrypted, "\0"); 
echo var_export($result, true) . "\n"; 

Выход:

70168f2d5751b3d3bf36b7e6b8ec5843 
'Lorem ipsum' . "\0" . '' . "\0" . '' . "\0" . '' . "\0" . '' . "\0" . '' 
'Lorem ipsum' 
+0

Это дало мне результат, но похоже, что ошибка вызвана base64_decode. Ответ - это все неизвестные символы, такие как «?» и т. д. Может быть проблема UTF 8? Как вы думаете? –

+0

Думаете, это проблема с base64 и HTTP2 на nginx? –

-1

У меня также были некоторые проблемы с расшифровкой данных, зашифрованных с помощью mcrypt_encrypt с openssl_decrypt. Следующий небольшой тест шифрует строку с mcrypt и openssl (с добавлением нулевого заполнения и без) и дешифрует все строки с помощью обоих методов. В этом примере используется режим ECB, но вы можете легко изменить его на CBC, добавив IV, если это необходимо.

// Setup key and test data 
$key = hash("sha256", 'test', true); 
$data = 'Hello World'; 
$enc = $dec = []; 
// Encrypt with MCRYPT_RIJNDAEL_128 method 
$enc['RIJ'] = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB)); 
// Encrypt with OpenSSL equivalent AES-256 
$enc['AES'] = base64_encode(openssl_encrypt($data, 'aes-256-ecb', $key, OPENSSL_RAW_DATA)); 
// Encrypt with OpenSSL equivalent AES-256 and added zero padding 
if (strlen($data) % 8) $data = str_pad($data, strlen($data) + 8 - strlen($data) % 8, "\0"); 
$enc['AES0'] = base64_encode(openssl_encrypt($data, 'aes-256-ecb', $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING)); 
// Decrypt all strings with MCRYPT_RIJNDAEL_128 
$dec['mRIJ'] = bin2hex(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($enc['RIJ']), MCRYPT_MODE_ECB)); 
$dec['mAES'] = bin2hex(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($enc['AES']), MCRYPT_MODE_ECB)); 
$dec['mAES0'] = bin2hex(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($enc['AES0']), MCRYPT_MODE_ECB)); 
// Decrypt all strings with OpenSSL equivalent AES-256 
$dec['oRIJ'] = bin2hex(openssl_decrypt(base64_decode($enc['RIJ']), 'aes-256-ecb', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING)); 
$dec['oAES'] = bin2hex(openssl_decrypt(base64_decode($enc['AES']), 'aes-256-ecb', $key, OPENSSL_RAW_DATA)); 
$dec['oAES0'] = bin2hex(openssl_decrypt(base64_decode($enc['AES0']), 'aes-256-ecb', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING)); 
// Print results 
print_r($enc); 
var_dump($dec); 

print_r и var_dump выход заключается в следующем:

Array 
(
    [RIJ] => YcvcTwAMLUMBCZXu5XqoEw== 
    [AES] => +AXMBwkWlgM1YDieGgekSg== 
    [AES0] => YcvcTwAMLUMBCZXu5XqoEw== 
) 
array(6) { 
    ["mRIJ"]=> 
    string(32) "48656c6c6f20576f726c640000000000" 
    ["mAES"]=> 
    string(32) "48656c6c6f20576f726c640505050505" 
    ["mAES0"]=> 
    string(32) "48656c6c6f20576f726c640000000000" 
    ["oRIJ"]=> 
    string(32) "48656c6c6f20576f726c640000000000" 
    ["oAES"]=> 
    string(22) "48656c6c6f20576f726c64" 
    ["oAES0"]=> 
    string(32) "48656c6c6f20576f726c640000000000" 
} 

Если вам нужен тот же зашифрованную строку с методами OpenSSL, как вы были с Mcrypt, вы будете иметь добавить нулевое заполнение вручную строка (AES0 в примере).Таким образом, вы получите точно такие же зашифрованные и дешифрованные строки, как и раньше. Для получения дополнительной информации об нулевом отступе вы должны посмотреть на ответ Джо: php: mcrypt_encrypt to openssl_encrypt, and OPENSSL_ZERO_PADDING problems

Если вы не хотите вручную добавлять нулевое дополнение ко всем новым сообщениям, вам понадобятся разные флаги для дешифрования старого mcrypt - зашифрованные сообщения и новые сообщения, зашифрованные с помощью openssl. Для старых сообщений вам необходимо использовать флаг OPENSSL_ZERO_PADDING ($dec['oRIJ'] в примере), тогда как вы не должны использовать его для зашифрованных сообщений openssl ($dec['oAES'] в примере). В моем случае я использовал этот подход, потому что поведение по умолчанию openssl по умолчанию более корректно для меня как для mcrypt: если вы зашифруете строку с 11 байтами, вы получите строку с 11 байтами после ее дешифрования. Как вы можете видеть в примере, это не так с mcrypt или с openssl и добавленным нулевым дополнением. В этих случаях вам нужно будет удалить задние нули вручную, чтобы вернуть исходные данные.

+0

1. Вопрос заключается в использовании режима CBC с IV, этот ответ не отвечает и поэтому не отвечает на вопрос. 2. * «зашифрованная строка отличается для обоих методов» * - это ошибка, с теми же входами зашифрованные данные должны быть одинаковыми. – zaph

+0

1) Вопрос был: «Как расшифровать после стирания Mcrypt?» к которому относится этот ответ. Пример можно легко настроить в любом конкретном режиме. 2) Причиной этого является отсутствие нулевого заполнения, которое объяснил ответ Джо. Также вопрос был о расшифровке, моя дополнительная информация о шифровании была просто «дополнительной». – Konrad

+0

Рассмотрите возможность обновления ответа для адресации этих точек в коде. – zaph