php encryption cryptography mcrypt php-openssl

php - Conversión MCrypt rijndael-128 a OpenSSL aes-128-ecb



encryption cryptography (3)

En su ejemplo específico, descubrí que al cambiar aes-128-ecb a aes-256-ecb , produce el mismo resultado que el mcrypt_encrypt heredado.

Como Mcrypt está en desuso, quiero usar OpenSSL en mi código, ya que ya usamos php 7.0.17 en nuestro servidor y no se sabe cuándo lo actualizarán.

Algunas API de terceros (alojadas en PHP 5.x probablemente y usando mcrypt ) están tomando datos cifrados. Han proporcionado métodos que están utilizando para cifrar / descifrar cadenas.

Aqui estan ellos

$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); }

usando estos métodos string small1 si se encripta se convierte en v7IXp5vVaFVXXlt/MN8BVw==

Queremos usar openssl_encrypt de nuestro lado, de modo que si ciframos la misma cadena con OpenSSL debe dar los mismos resultados que Mcrypt. He investigado que mcrypt usando rijndael-128 Mode ecb debería ser compatible con OpenSSL aes-128-ecb .

Durante las últimas horas, he intentado crear mi propio método para cifrar cadenas que ofrecen el mismo resultado utilizando OpenSSL. Hasta ahora he llegado a esto

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

Pero produce diferentes cadenas SxJ3+EdaeItZx3/EwGTUbw== para lo mismo que la entrada anterior. No sé si es un problema de bandera o relleno, cualquier indicador será bienvenido.

He agregado el código aquí para probar en línea https://3v4l.org/v2J2N

Gracias por adelantado.


Esto es lo que funcionó para mí:

<?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); }


Lo más probable es que se esperaba que la clave se usara como hexadecimal (ya está en formato hexadecimal) y no como una cadena para convertirla en hexadecimal.

mcrypt:

mcrypt no admite el mcrypt estándar PKCS # 7 (née PKCS # 5), solo el relleno nulo no estándar pero el relleno se agrega explícitamente antes de mcrypt .

El cifrado v7IXp5vVaFVXXlt/MN8BVw== es el cifrado correcto basado en el relleno PKCS # 7. Modo ECB y la clave como una cadena.

Ver: mcrypt - CALCULADORA AES .

En hexadecimal, observe que el relleno de datos es claramente visible:
key: 6130613765373939376236643566636435356634623563333236313162383763
data: 736D616C6C310A0A0A0A0A0A0A0A0A0A
encrypted: BFB217A79BD56855575E5B7F30DF0157

En Base64:
encrypted: v7IXp5vVaFVXXlt/MN8BVw==

OpenSSL:

Observe que la clave es de 256 bits, pero la llamada OpenSSL con "aes-128-ecb" parece implicar una clave de 128 pero. Entonces las llaves no coinciden.

Ver: OpenSSL - CALCULADORA AES

En hexadecimal, observe que el relleno de datos es claramente visible:
key: 61306137653739393762366435666364
data: 736D616C6C310A0A0A0A0A0A0A0A0A0A
encrypted: 4B1277F8475A788B59C77FC4C064D46F

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