c – How do I use AES_CBC_Encrypt 128 openssl properly in Ubuntu?

c – How do I use AES_CBC_Encrypt 128 openssl properly in Ubuntu?

I managed to figure out my grave mistake. The line:

AES_set_encrypt_key(k_j, sizeof(k_j), &enc_key);

should be:

AES_set_encrypt_key(k_j, sizeof(k_j)*8, &enc_key);

Also the enclength and declength in the AES_CBC_Encrypt() function should be the same apparently. So I used 48bytes for both encryption and decryption, otherwise it didnt work for me. I could be wrong but when I used strlen(buffer2) for encryption (which is 40bytes) the decryption only managed to decrypt part of the string correctly, the rest of it was still gibberish characters. – val37

I struggled with that bad documented API of OpenSSL myself. It really doesnt help that the functions itself are implemented in Assembler, so even the sources are not helping. But I was able to identify some mistakes youve made:

  1. As youve stated, AES_set_encrypt_key takes bit-size as second parameter, not bytes.
  2. The key must be exactly of sizes 16, 24, or 32 bytes.
  3. The given init_vector must be the same at start of encryption and decryption.

Because of 2. your whole example wont work with sha1. MD5_DIGEST_LENGTH and has 16 bytes (128 bit) just by coincidence. The initialization vector also gets changed by the encryption operation, so you could add additional data to the block chain again and again. But since you were not following 3. and used the changed vector for decryption without resetting it first, thats why your decryption returns gibberish characters.

As an example I took your code, threw out anything unnecessary, and extracted the encrypt/decrypt operations for clearing up the important parts:

void encrypt(unsigned char* buf, size_t length, const AES_KEY* const enc_key, const unsigned char* iv)
{
  unsigned char local_vector[AES_BLOCK_SIZE];
  memcpy(local_vector, iv, AES_BLOCK_SIZE);

  AES_cbc_encrypt(buf, buf, length, enc_key, local_vector, AES_ENCRYPT);
}

Im working on buf for reading and writing. As you can see the init_vector gets copied locally to keep the original constant. I did the similar for decryption.

void decrypt(unsigned char* buf, size_t length, const AES_KEY* const dec_key, const unsigned char* iv)
{
  unsigned char local_vector[AES_BLOCK_SIZE];
  memcpy(local_vector, iv, AES_BLOCK_SIZE);

  AES_cbc_encrypt(buf, buf, length, dec_key, local_vector, AES_DECRYPT);
}

And here is what I did with your code. I havent changed fscanf, because we should focus on the asked problem instead of confusing people:

void tst_function()
{
  FILE *fp=fopen(alice.txt,r); //read mode
  char buffer1[128], buffer2[128]; //buffer1->names, buffer2->data
  memset(buffer1, 0, sizeof(buffer1));
  memset(buffer2, 0, sizeof(buffer2));
  // remember, this wont work with any other size
  unsigned char k_j[AES_BLOCK_SIZE];

  //until end of file
  while(fscanf(fp,%s %sn,(char*)&buffer1, (char*)&buffer2) > 0)
  {
     printf(Reading %s %40sn, buffer1, buffer2);
     printf(original:t%sn, buffer2);

     unsigned char init_vector[AES_BLOCK_SIZE];
     RAND_bytes(init_vector, AES_BLOCK_SIZE);

     // PKCS 5 Padding
     // ((inputs_length + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
     const size_t encslength = 48;
     unsigned char enc_out[encslength];
     memset(enc_out, 0, sizeof(enc_out));
     strncpy(enc_out, buffer2, sizeof(enc_out));

     AES_KEY enc_key, dec_key;
     AES_set_encrypt_key(k_j, sizeof(k_j)*8, &enc_key);
     AES_set_decrypt_key(k_j, sizeof(k_j)*8, &dec_key);

     encrypt(enc_out, encslength, &enc_key, init_vector); //see above
     printf(encrypted:t%sn, (char*)enc_out);

     decrypt(enc_out, encslength, &dec_key, init_vector); //see above
     printf(decrpyted:t%sn, (char*)enc_out);
   }
   fclose(fp);
}

It now does what one would expect it to do. You have to be extremely careful about the key size. I crashed a lot because of dangling zeros (from strings) I wasnt aware of. Additionally you could take a look into EVP Symmetric Encryption and Decryption and XTS for keys up to 512 bit.

c – How do I use AES_CBC_Encrypt 128 openssl properly in Ubuntu?

Leave a Reply

Your email address will not be published.