Pregunta

Antes he logró puerto algún código C ++ CryptoPP Rijndael_128 CBC a MCrypt PHP, pero ahora estoy teniendo problemas con el modo CFB. Los resultados C ++ y PHP no coinciden (así los primeros partidos de bytes, pero esto podría ser una coincidencia, todo lo demás no lo hace). Con algunos diagnósticos, parece que mcrypt de PHP no está fijando la longitud de la clave correctamente?

Aquí está el C ++ (diagnósticos y artículos diversos eliminan por simplicidad):

CFB_Mode<AES>::Encryption encryptor(g_encrypt_key, AES::DEFAULT_KEYLENGTH, g_encrypt_iv);

StringSource ss( sInput.c_str(), true, 
        new StreamTransformationFilter( encryptor, 
            new HexEncoder( new StringSink( sEncryptedOut ) )
        ));

Y aquí está el PHP:

$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CFB, '')
mcrypt_generic_init($cipher, $g_encrypt_key, $g_encrypt_iv);

$sEncryptedOutput = mcrypt_generic( $cipher, $sInput);
mcrypt_generic_deinit($cipher);
mcrypt_module_close($cipher);

g_encrypt_key y g_encrypt_iv son ambos de 16 bytes de largo, y los bytes de partido para el C ++ y versiones de PHP. Para la versión de PHP es una cadena binaria construida a partir de los bytes (sí he comprobado estos son idénticos).

He añadido las llamadas a la versión de PHP para el tamaño del bloque de verificación de $cipher, tamaño de la clave, etc. El tamaño de bloque y el tamaño iv son ambos 16; tamaños de clave soportados son reportados como 16, 24 y 32 -. todo como se esperaba

Cuando creo que el problema es, es que el tamaño de clave está siendo reportado como 32 bytes. En cuanto a los documentos de mcrypt, la única manera de establecer el tamaño de clave es mediante el suministro de una llave del tamaño requerido. Pero yo estoy pasando una clave de 16 bytes! Así que ¿por qué se reporta la presencia de una clave de 32 bytes? Si el modo CFB debe utilizar una clave de 32 bytes, entonces ¿por qué aceptar CryptoPP como bien? ¿Cuál es la solución? ¿Puedo forzar PHP para utilizar la clave de 16 bytes que se ha proporcionado? ¿O hay un parámetro que me falta que está por defecto a un entorno diferente en CryptoPP que en MCrypt?

Estoy utilizando el modo CFB porque quiero minimizar la longitud de los datos cifrados resultantes. Los pocos bytes de relleno que introduciría, importan en esta aplicación.

Tengo que ser capaz de cifrar / descifrar en C ++, pero sólo cifrar en PHP. AES es sin duda una exageración para mi aplicación -. La necesidad mínimo que es "una buena codificación de los bytes", por lo que la función de bytes individuales en los datos no son evidentes

¿Fue útil?

Solución

Ha sido un tiempo, pero tuve algunos problemas similares con mcrypt y openSSL utilizando CFB hace un par de años. Al final, descubrí mcrypt utilizó un tamaño de cadena de realimentación predeterminado diferente que openssl en modo CFB. Es decir, creo que un AES128 openSSL en CFB utiliza un tamaño de tamaño de bloque y la retroalimentación de 128 bits, mientras que mcrypt utiliza un tamaño de bloque de 128 bits y un tamaño de votaciones de 8 bits. No tengo ninguna manera de confirmar esto, era sólo una especulación en el momento en base a la lectura de algunos mensajes en el foro de edad. Independientemente de la verdad de esa teoría, yo no era la única persona o primeros en tener este tema en particular.

La solución para mí era utilizar nofb como a ti mismo. De acuerdo con la PHP mcrypt referencia de la biblioteca fuerzas MCRYPT_MODE_NOFB la cadena de realimentación para igualar el tamaño de bloque del algoritmo, en este caso una de 128 bits de bloque / realimentación para AES128 (Rijndael), que coincide con lo que el página de manual de los estados de los módulos mcrypt sobre nofb. Esto es bueno, ya que todo me encontré con dicha realimentación nofb es sincrónico con el tamaño de bloque. De este modo, tanto mcrypt y OpenSSL en nofb ahora eran clave de 128 bits / IV / block / tamaños de retroalimentación para AES128 y todo funcionaba bien.

En lo que PHP KeySizes 256 bits de informes (32 bytes), la función que devuelve el tamaño actual clave de cifrado-algoritmo realidad devuelve el tamaño de clave máxima, que no se indica claramente en la documentación. Lo sé porque mi pequeña clase utilizo todo el tiempo ahora para diversos proyectos funciona perfectamente bien con openSSL y cualquier otra biblioteca de AES en CSC o nofb. Este no sería el caso si se mcrypt carnes de clave de 128 bits mi (16 caracteres) con un 128 bits adicionales de cadena nula, o lo que sea, y no sería técnicamente correcto de todos modos.

No es realmente una buena respuesta, pero lo mejor que tengo sobre la base de una incursión muy amateur en la criptografía hace varios años.

Otros consejos

Salida phpseclib:

http://phpseclib.sourceforge.net/

Se puede configurar el tamaño de la clave y el tamaño del bloque a lo que quieras.

por ejemplo. $ AES> setKeyLength (128) o $ AES> setKeyLength (256);

he tenido este problema - par de puntos. Por defecto, el modo de PHP Rijndael establece el circuito de retroalimentación para 8bits - para ser AES es necesita ser la misma longitud que el IV / Key

.

Se puede hacer esto mediante el uso de la modalidad 'NCFB' en lugar de 'CFB' o MCRYPT_MODE_CFB.

Los detalles completos de la escritura aes_cfb_128 PHP son compatibles en esta pregunta de seguridad Stackexchange: aes CFB 128 descifrado / cifrado problema entre Erlang y PHP . El corto de él es (de Tom Leek):

  

... para los dos CFB y OFB (que son distintos entre sí y no pueden usarse indistintamente), usted tiene que preocuparse acerca de la "longitud de retroalimentación" que no necesariamente se documentó con gran claridad en varias bibliotecas criptográficas. Tanto el cifrado y descifrado deben usar la misma longitud de realimentación para interoperar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top