Esta pregunta es la continuación de la última, con respecto a How to make Ruby AES-256-CBC and PHP MCRYPT_RIJNDAEL_128 play well together. Lo estoy trabajando ahora, pero todavía estoy luchando por ir en la otra dirección. El criptograma generado por PHP parece tener toda la información que se proporcionó, pero no puedo obtener el código de Ruby para descifrarlo sin error.Parte II: Cómo hacer que Ruby AES-256-CBC y PHP MCRYPT_RIJNDAEL_128 jueguen bien juntos
Aquí está el código PHP que estoy usando para generar el criptograma:
$cleartext = "Who's the clever boy?";
$key = base64_decode("6sEwMG/aKdBk5Fa2rR6vVw==\n");
$iv = base64_decode("vCkaypm5tPmtP3TF7aWrug==");
$cryptogram = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $cleartext, MCRYPT_MODE_CBC, $iv);
$result = base64_encode($cryptogram);
print "\n'$result'\n";
RESULT
'JM0OxMINPTnF1vwXdI3XdKI0KlVx210CvpJllFja+GM='
Entonces aquí está el intento de descifrar en Ruby:
>> cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
>> cipher.key = Base64.decode64("6sEwMG/aKdBk5Fa2rR6vVw==\n")
>> cipher.iv = Base64.decode64("vCkaypm5tPmtP3TF7aWrug==")
>> cryptogram = Base64.decode64('JM0OxMINPTnF1vwXdI3XdKI0KlVx210CvpJllFja+GM=')
>> cleartext = cipher.update(cryptogram)
=> "Who's the clever"
>> cleartext << cipher.final
OpenSSL::Cipher::CipherError: bad decrypt
from (irb):100:in `final'
from (irb):100
Lo que es realmente frustrante de esto es que es posible obtener todo el texto sin formato de esa cadena encriptada. Repitiendo lo anterior, pero añadiendo una almohadilla sin sentido para el criptograma:
>> cleartext = cipher.update(cryptogram + 'pad')
=> "Who's the clever boy?\000\000\000\000\000\000\000\000\000\000\000"
>> cleartext << cipher.final
OpenSSL::Cipher::CipherError: bad decrypt
from (irb):119:in `final'
from (irb):119
En mi caso uso real del texto claro está estructurado (una cadena JSON, ya que preguntas), así que me siento cómoda una este punto que me di cuenta utilice este esquema y detecte la entrada mal encriptada sin realizar el cipher.final
. Sin embargo, no puedo tolerar este tipo de kludge en mi código, así que me gustaría entender cómo hacer que el código de rubí maneje el último bloque con gracia.
Gracias por su opinión, caf. Agregar texto al texto claro es simplemente crear una cadena diferente para encriptar; no cambia el resultado. Acepto que el problema tiene algo que ver con la forma en que las dos implementaciones se ocupan del último bloque de la secuencia cifrada. La salida de los dos algoritmos es idéntica hasta el último bloque de 32 bytes, donde los últimos 16 bytes son completamente diferentes. Me he quedado sin paciencia con el problema, así que a menos que algún samaritano venga y me lo resuelva, voy a ir con el kludge arriba. – dondo
El texto agregado al final del texto sin formato (relleno) tiene que ser de una forma muy específica, que el lado de Ruby está esperando. Investigaré qué método de relleno usa y actualizaré la respuesta. – caf
... El relleno de PKCS funciona al agregar n bytes de relleno de valor n para hacer que la longitud total de los datos ** encriptados sea un múltiplo del tamaño de bloque ... – dondo