Soy nuevo en OpenSSL. ¿Alguien puede darme una pista sobre cómo inicializar el modo AES CTR desde un archivo C? Sé que esta es la firma del método, pero tengo problemas con los parámetros, no hay mucha documentación ni un ejemplo claro de cómo hacer un simple cifrado. Agradecería si alguien pudiera ejemplificar una llamada a este método. ¡Gracias por adelantado!AES CTR 256 Modo de operación de cifrado en OpenSSL
void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
const unsigned long length, const AES_KEY *key,
unsigned char ivec[AES_BLOCK_SIZE],
unsigned char ecount_buf[AES_BLOCK_SIZE],
unsigned int *num);
Hola Caf realmente aprecio su respuesta rápida ha sido muy útil, y defenetly el mejor ejemplo que he encontrado en la web. Intento abrir un archivo con una longitud indeterminada, encriptarlo y escribir otro archivo con el texto cifrado generado, luego abrir el archivo cifrado y recuperar el texto sin formato. Necesito usar un archivo de una cantidad considerable de MB porque me gustaría comparar el rendimiento de la CPU. Sin embargo, sigo teniendo un problema al descifrar. De alguna manera, al descifrar un número considerable de archivos de texto (1504 KB) no se descifrará por completo, y la mitad se encuentra en texto sin formato y la otra mitad aún cifrada. Creo que esto podría estar relacionado con el tamaño del iv o la forma en que estoy llamando al contador. Aquí es lo que tengo hasta ahora:
#include <openssl/aes.h>
#include <stdio.h>
#include <string.h>
struct ctr_state {
unsigned char ivec[16];
unsigned int num;
unsigned char ecount[16];
};
FILE *fp;
FILE *rp;
FILE *op;
size_t count;
char * buffer;
AES_KEY key;
int bytes_read, bytes_written;
unsigned char indata[AES_BLOCK_SIZE];
unsigned char outdata[AES_BLOCK_SIZE];
unsigned char ckey[] = "thiskeyisverybad"; // It is 128bits though..
unsigned char iv[8] = {0};//This should be generated by RAND_Bytes I will take into consideration your previous post
struct ctr_state state;
int init_ctr(struct ctr_state *state, const unsigned char iv[8]){
state->num = 0;
memset(state->ecount, 0, 16);
memset(state->ivec + 8, 0, 8);
memcpy(state->ivec, iv, 8);
}
void encrypt(){
//Opening files where text plain text is read and ciphertext stored
fp=fopen("input.txt","a+b");
op=fopen("output.txt","w");
if (fp==NULL) {fputs ("File error",stderr); exit (1);}
if (op==NULL) {fputs ("File error",stderr); exit (1);}
//Initializing the encryption KEY
AES_set_encrypt_key(ckey, 128, &key);
//Encrypting Blocks of 16 bytes and writing the output.txt with ciphertext
while (1) {
init_ctr(&state, iv); //Counter call
bytes_read = fread(indata, 1, AES_BLOCK_SIZE, fp);
AES_ctr128_encrypt(indata, outdata, bytes_read, &key, state.ivec, state.ecount, &state.num);
bytes_written = fwrite(outdata, 1, bytes_read, op);
if (bytes_read < AES_BLOCK_SIZE)
break;
}
fclose (fp);
fclose (op);
free (buffer);
}
void decrypt(){
//Opening files where text cipher text is read and the plaintext recovered
rp=fopen("recovered.txt","w");
op=fopen("output.txt","a+b");
if (rp==NULL) {fputs ("File error",stderr); exit (1);}
if (op==NULL) {fputs ("File error",stderr); exit (1);}
//Initializing the encryption KEY
AES_set_encrypt_key(ckey, 128, &key);
//Encrypting Blocks of 16 bytes and writing the output.txt with ciphertext
while (1) {
init_ctr(&state, iv);//Counter call
bytes_read = fread(indata, 1, AES_BLOCK_SIZE, op);
AES_ctr128_encrypt(indata, outdata, bytes_read, &key, state.ivec, state.ecount, &state.num);
bytes_written = fwrite(outdata, 1, bytes_read, rp);
if (bytes_read < AES_BLOCK_SIZE)
break;
}
fclose (rp);
fclose (op);
free (buffer);
}
int main(int argc, char *argv[]){
encrypt();
//decrypt();
system("PAUSE");
return 0;
}
Cada cifrar y descifrar la función también llamados en diferentes carreras así que todo se inicia siempre con los mismos valores. Gracias de nuevo por los consejos que me pueden proporcionar por adelantado & Saludos !!!
Tu problema es que estás reiniciando el contador después de cada bloque. Esto es incorrecto: mueve la llamada 'init_ctr()' fuera de los bucles 'while()' tanto en el cifrado como en el descifrado. 'indata' y' outdata' tampoco tienen que ser de longitud 'AES_BLOCK_SIZE'; pueden ser considerablemente más grandes. – caf
Debería * no * usar 'AES_encrypt' y sus amigos. Es una implementación de solo software, por lo que no disfrutará de soporte de hardware, como AES-NI. Deberías estar usando las funciones 'EVP_ *'. Ver [EVP Symmetric Encryption and Decryption] (http://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] (http://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption) en la wiki de OpenSSL. – jww
Si usa las funciones 'EVP_ *', las cifras de interés son 'EVP_aes_128_ctr',' EVP_aes_192_ctr' y 'EVP_aes_256_ctr'. – jww