2011-02-27 18 views
15

Me gustaría utilizar la biblioteca OpenSSL para descifrar algunos datos AES. El código tiene acceso a la clave. Este proyecto ya usa libopenssl para otra cosa, así que me gustaría seguir con esta biblioteca.Cómo hacer el descifrado AES con OpenSSL

Fui mirando directamente a /usr/include/openssl/aes.h ya que el sitio de OpenSSL es ligero en la documentación. La única función de descifrado es éste:

void AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); 

Desafortunadamente, esto no tiene una forma de especificar la longitud del puntero in, así que no estoy seguro de cómo funcionaría.

Existen varias otras funciones que creo que toman un parm numérico para diferenciar entre el cifrado y el descifrado. Por ejemplo:

void AES_ecb_encrypt(*in, *out, *key, enc); 
void AES_cbc_encrypt(*in, *out, length, *key, *ivec, enc); 
void AES_cfb128_encrypt(*in, *out, length, *key, *ivec, *num, enc); 
void AES_cfb1_encrypt(*in, *out, length, *key, *ivec, *num, enc); 
void AES_cfb8_encrypt(*in, *out, length, *key, *ivec, *num, enc); 
void AES_cfbr_encrypt_block(*in, *out, nbits, *key, *ivec, enc); 
void AES_ofb128_encrypt(*in, *out, length, *key, *ivec, *num); 
void AES_ctr128_encrypt(*in, *out, length, *key, ivec[], ecount_buf[], *num); 
void AES_ige_encrypt(*in, *out, length, *key, *ivec, enc); 
void AES_bi_ige_encrypt(*in, *out, length, *key, *key2, *ivec, enc); 

Por lo que entiendo el uso de Google, la enc Parm se establece en AES_ENCRYPT o AES_DECRYPT para especificar qué acción debe llevarse a cabo.

que me lleva a mis 2 preguntas:

  1. ¿Qué significan estos nombres? ¿Qué es ecb, cbc, cfb128, etc. ... y cómo decido cuál debería usar?
  2. ¿Cuál es el parmetro unsigned char *ivec necesario para la mayoría de estos, y de dónde lo obtengo?
+0

Debería * no * usar 'AES_encrypt' y sus amigos. Deberías estar usando las funciones 'EVP_ *'. Consulte [EVP Symmetric Encryption and Decryption] (https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption) en la wiki de OpenSSL.De hecho, probablemente debería estar usando el cifrado autenticado porque proporciona * ambos * confidencialidad y autenticidad. Ver [EVP Authenticated Encryption and Decryption] (https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption) en la wiki de OpenSSL. – jww

Respuesta

18

No hay tamaño dado porque los tamaños de bloque para AES se fijan basado en el tamaño de la clave ; ha encontrado la implementación del modo ECB, que no es adecuada para uso directo (excepto como herramienta de enseñanza).

ECB, CBC, CFB128, etc., son todos los nombres abreviados de modes of operation que son de uso común. Tienen diferentes propiedades, pero si nunca tocas el modo ECB, deberías estar bien.

Sugiero quedarme más lejos del código de bajo nivel; use las interfaces EVP_* en su lugar, si puede, y puede mover algunas de estas decisiones en un archivo de configuración de texto, para que los usuarios puedan seleccionar fácilmente entre las diferentes cifras, tamaños de bloques y modos de operación si alguna vez hay una buena razón para cambiar de los valores predeterminados.

Mis simpatías, la documentación de OpenSSL se siente peor de lo que es, y no es tan genial. Puede encontrar Network Security with OpenSSL un libro útil. Desearía haberlo encontrado antes la última vez que necesité usar OpenSSL. (No deje que el título tonto te engañe - es debe haberse titulado simplemente "OpenSSL" Oh, bueno..)

Editar me olvidó mencionar la initialization vectors. Se usan para asegurarse de que si cifra los mismos datos con la misma clave, el texto cifrado no será idéntico. Necesitas el IV para descifrar los datos, pero no necesitas mantener el IV en secreto. Debe generar uno aleatoriamente para cada sesión (y enviarlo junto con una clave de sesión RSA o El Gamal o DH-encrypted) o generarlo de manera idéntica en ambos puntos finales, o almacenarlo localmente con el archivo, algo así.

+4

"No hay tamaño dado porque los tamaños de bloques para AES se fijan en función del tamaño de la clave", en realidad no; están fijos a 16 bytes, independientemente del tamaño de la clave. Y la razón por la que AES_decrypt no toma un tamaño es porque solo descifra un bloque, por lo que la longitud se fija en 16. – Jumbogram

+1

Tenga en cuenta que si está descifrando un mensaje cifrado por otro proceso fuera de su control, el cifrado de bloque modo (CBC, CFB etc.) será especificado por ese proceso. El vector de inicialización debe ser suministrado junto con el texto cifrado. – caf

+1

Tenga en cuenta que Java, cuando se le indica que use AES sin especificar nada más, se predetermina al modo ECB. Una vez que entendí eso y para qué eran todas estas funciones, las cosas tuvieron mucho más sentido. Ahora tengo mi código C/C++ usando OpenSSL para descifrar la carga útil que proviene de esta aplicación Java específica. –

Cuestiones relacionadas