LINUX.ORG.RU

Замена mcrypt (php) на openssl (shell)

 , ,


0

1

Приветствую! В общем задача - заменить mcrypt_encrypt имеющийся не во всех конфигурациях php (нет возможности подгрузить библиотеку для этого) на шелловую команду вокруг openssl (которую можно выполнить на имеющейся конфигурации). Предполагается что результат должен быть идентичным.

Но пока не получается - прошу помочь.

(полагаю проблема в упаковке ключа и вектора в hex.. в php это делается для передачи в mcrypt а в shell_exec непонятно как передать верно ключ и вектор, либо алгоритмы не совсем совпадающие но нужен результат аналогичный php)

<?php
    # --- ШИФРОВАНИЕ ---

    $key = pack('H*', "189cebc45c7caec5c57894564c52ae5646ed4564565ccc4565ec555dd5dd4d54");
    echo "Ключ: " . $key . "\n";

    $key_size =  strlen($key);
    echo "Длина ключа: " . $key_size . "\n";

    $plaintext = "This string was must be encrypted";
     echo "Исходник: " . $plaintext . "\n";

    $iv = pack('H*', "e4554c4564a5454cc45654a45654ce44");
    echo "Инициализирующий вектор: " . $iv . "\n";

    $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key,
                                 $plaintext, MCRYPT_MODE_CBC, $iv);

    $ciphertext_base64 = base64_encode($ciphertext);

    echo  "\n"."Зашифровано:".$ciphertext_base64 . "\n\n";

    # --- ДЕШИФРОВКА ---

    $ciphertext_dec = base64_decode($ciphertext_base64);

    $iv_dec=$iv;

    $plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key,
                                    $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);

    echo  "Расшифровано:".$plaintext_dec . "\n\n";



$shkey="189cebc45c7caec5c57894564c52ae5646ed4564565ccc4565ec555dd5dd4d54";
$shiv="e4554c4564a5454cc45654a45654ce44";

$cmd='echo '.$plaintext.' | openssl aes-128-cbc -base64 -nosalt -a -k '.$shkey.' -iv '.$shiv;
echo "Command:".$cmd."\n";
$output = shell_exec($cmd);
echo "\n"."Output:$output"."\n";

?>


На данный момент методом проб прояснил что в openssl метод скорее нужно применять aes-256-cbc . И дополнительно вопрос с паддингом - для mcrypt_decrypt скорее всего нужно делать что то типа:

    $plaintext = "Thisstring";

    $block = 16;
    $pad   = $block - (strlen($plaintext) % $block);
    $plaintextn = $plaintext.str_repeat(chr($pad), $pad);
тогда условия будут более мене равны на входе, так как openssl по умолчанию паддинг делает автоматом (или ключем -nopad отключать, но тогда ругается)

Осталось дело за малым, почему сюда и написал:

как вот такое $iv = pack('H*', «e4554c4564a5454cc45654a45654ce44»);

подать в строку с openssl ... -iv .... что бы e4554c4564a5454cc45654a45654ce44 воспринимались как шестнадцатиричные. Или они итак воспринимаются норм.. не понятно.

DJArty
() автор топика
Ответ на: комментарий от DJArty

Еще наблюдение - если для iv менять регистр букв то результат шиврования не меняется - вывод: в строке после iv вектор воспринимается как шестнадцатиричное без всяких представлений. Для -к такой номер не проходит, но можно достать из файла упакованное хекс значение ключа. Тем не менее пока нет совпадения.

DJArty
() автор топика

Новый вариант

Обновленный вариант. Кроме mcrypt_encrypt добавлен openssl_encrypt (на замену первому приходит) и с ними удалось получить одинаковый вариант применив паддинг и 256. Но командный openssl все еще не дает искомого совпадения...

<?php
    # --- ШИФРОВАНИЕ ---

    $key = pack('H*', "189cebc45c7caec5c57894564c52ae5646ed4564565ccc4565ec555dd5dd4d54");
    file_put_contents("k.key",$key);
    echo "Ключ: " . $key . "\n";
    
    $key_size =  strlen($key);
    echo "Длина ключа: " . $key_size . "\n";
    
    $iv = pack('H*', "e4554c4564a5454cc45654a45654ce44");
    echo "Инициализирующий вектор: " . $iv . "\n";
    
    $plaintext = "Thisstringff";
    $block = 16;
    $pad   = $block - (strlen($plaintext) % $block);
    $plaintextn = $plaintext.str_repeat(chr($pad), $pad);

     echo "Исходник:" . $plaintext . "<-\n";
     echo "size:".strlen($plaintext). "<-\n";
     echo "Исходник паддинг:" . $plaintextn . "<-\n";
     echo "size паддинг:".strlen($plaintextn). "<-\n";
    
     file_put_contents("pt.in",$plaintext);
     file_put_contents("ptn.in",$plaintextn);

    $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key,$plaintextn, MCRYPT_MODE_CBC,$iv);
    
    $ciphertext_base64 = base64_encode($ciphertext);
    
    echo  "\n"."Зашифровано:".$ciphertext_base64 . "\n\n";
    
    # --- ДЕШИФРОВКА ---

    $ciphertext_dec = base64_decode($ciphertext_base64);

    $plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key,$ciphertext_dec, MCRYPT_MODE_CBC,$iv);

    echo  "Расшифровано:".$plaintext_dec . "\n\n";

function sslEncrypt128($str, $secret,$iv)
{
    return base64_encode(openssl_encrypt($str, 'aes-256-cbc', $secret, OPENSSL_RAW_DATA,$iv));
}

echo  "\n"."Зашифровано openssl_encrypt:";
var_dump(sslEncrypt128($plaintext, $key,$iv));


$shkey="189cebc45c7caec5c57894564c52ae5646ed4564565ccc4565ec555dd5dd4d54";
$shkeypack="k.key";
$shiv="e4554c4564a5454cc45654a45654ce44";

#$cmd='echo '.$plaintext.' | openssl aes-256-cbc -nosalt -a -k '.$shkey.' -iv '.$shiv;
$cmd='openssl aes-256-cbc  -in "pt.in" -nosalt -a -A -k "'.$shkey.'" -iv "'.$shiv.'"';
echo "\nCommand:".$cmd."\n";
$output = shell_exec($cmd);
echo "\n"."Зашифровано openssl:$output"."\n";

$cmd='openssl aes-256-cbc  -in "pt.in" -nosalt -a -A -kfile "'.$shkeypack.'" -iv "'.$shiv.'"';
echo "\nCommand:".$cmd."\n";
$output = shell_exec($cmd);
echo "\n"."Зашифровано openssl kfile:$output"."\n";
?>

DJArty
() автор топика

Решение

Чьёрт ... докопался - нужно ключ -K применять а не -k :o)

DJArty
() автор топика
Ответ на: комментарий от pekmop1024

Вопрос скорее теоретический чем всемнужнопрактический..

DJArty
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.