web-dev-qa-db-fra.com

MCrypt rijndael-128 à OpenSSL aes-128-ecb conversion

Puisque Mcrypt est obsolète, je veux utiliser OpenSSL à la place dans mon code car nous utilisons déjà php 7.0.17 dans notre serveur et il n'y a aucun moyen de savoir quand ils sont mis à niveau il.

Certaines API tierces (hébergées sur PHP 5.x probablement et utilisant mcrypt ), prend des données cryptées. Ils ont fourni des méthodes qu'ils utilisent pour crypter/décrypter les chaînes.

Les voici

$secret = 'a0a7e7997b6d5fcd55f4b5c32611b87c' ;

public function encrypt128($str)
    {
        $block = mcrypt_get_block_size("rijndael_128", "ecb");
        $pad   = $block - (strlen($str) % $block);
        $str .= str_repeat(chr($pad), $pad);

        return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $secret, $str, MCRYPT_MODE_ECB));
    }

public function decrypt128($str)
    {
        $str = base64_decode($str);
        $str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $secret, $str, MCRYPT_MODE_ECB);

        $len = strlen($str);
        $pad = ord($str[$len - 1]);

        return substr($str, 0, strlen($str) - $pad);
    }

en utilisant ces méthodes chaîne small1 si crypté devient v7IXp5vVaFVXXlt/MN8BVw==


Nous voulons utiliser openssl_encrypt de notre côté de telle sorte que si nous chiffrons la même chaîne avec OpenSSL elle doit donner les mêmes résultats que Mcrypt. J'ai recherché que mcrypt en utilisant rijndael-128 Mode ecb devrait être compatible avec OpenSSL aes-128-ecb.

Depuis quelques heures, j'essaie de créer ma propre méthode pour crypter les chaînes servant le même résultat en utilisant OpenSSL. Jusqu'à présent, je suis venu à cette

public function sslEncrypt128($str)
{
    $secret = 'a0a7e7997b6d5fcd55f4b5c32611b87c';
    return base64_encode(openssl_encrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA));
}

Mais il produit une chaîne différente SxJ3+EdaeItZx3/EwGTUbw== comme pour l'entrée ci-dessus. Je ne sais pas si c'est un problème de drapeau ou de rembourrage, tout pointeur sera le bienvenu.

J'ai ajouté le code ici pour tester en ligne https://3v4l.org/v2J2N

Merci d'avance.

13
Jamshad Ahmad

Dans votre exemple spécifique, j'ai constaté qu'en changeant aes-128-ecb à aes-256-ecb, il produit la même sortie que l'héritage mcrypt_encrypt.

5
Michael Butler

Voici ce qui a fonctionné pour moi:

<?php

$str = 'Content';
if (strlen($str) % 16) {
    $str = str_pad($str, strlen($str) + 16 - strlen($str) % 16, "\0");
}

$key = 'KEY';
if (strlen($key) % 16) {
    $key = str_pad($key, strlen($key) + 16 - strlen($key) % 16, "\0");
}

$res1 = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB);
echo strToHex($res1) . ' | mcrypt_encrypt';

echo "<hr>";
echo strToHex(openssl_decrypt($res1, "aes-128-ecb", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING)) . ' | openssl_decrypt';

echo "<hr>";

$res2 = openssl_encrypt($str, "aes-128-ecb", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);
echo strToHex($res2) . ' | openssl_encrypt';

echo "<hr>";
echo strToHex(openssl_decrypt($res2, "aes-128-ecb", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING)) . ' | openssl_decrypt';


function strToHex($string) {
    $hex = '';
    for ($i = 0; $i < strlen($string); $i++) {
        $ord     = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex     .= substr('0' . $hexCode, -2);
    }

    return strToUpper($hex);
}
3
Roland Soós

Très probablement, la clé devait être utilisée en hexadécimal (elle est déjà au format hexadécimal) et non en tant que chaîne à convertir en hexadécimal.


mcrypt:

mcrypt ne prend pas en charge le remplissage standard PKCS # 7 (née PKCS # 5), uniquement le remplissage nul non standard mais le remplissage est explicitement ajouté avant mcrypt .

Le chiffrement v7IXp5vVaFVXXlt/MN8BVw== est le chiffrement correct basé sur le remplissage PKCS # 7. Mode ECB et la clé sous forme de chaîne.

Voir: mcrypt - CALCULATEUR AES .

En hexadécimal, notez que le remplissage des données est clairement visible:
key: 6130613765373939376236643566636435356634623563333236313162383763
data: 736D616C6C310A0A0A0A0A0A0A0A0A0A
encrypted: BFB217A79BD56855575E5B7F30DF0157

Dans Base64:
encrypted: v7IXp5vVaFVXXlt/MN8BVw==


OpenSSL:

Notez que la clé est de 256 bits, mais l'appel OpenSSL avec "aes-128-ecb" semble impliquer une clé de 128 bits. Les clés ne correspondent donc pas.

Voir: OpenSSL - CALCULATEUR AES

En hexadécimal, notez que le remplissage des données est clairement visible:
key: 61306137653739393762366435666364
data: 736D616C6C310A0A0A0A0A0A0A0A0A0A
encrypted: 4B1277F8475A788B59C77FC4C064D46F

Dans Base64:
encrypted: SxJ3+EdaeItZx3/EwGTUbw==

2
zaph