6
votes

I am trying to use openssl to encrypt/decrypt message using AES. After coming through the following study: https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption http://www.itc.edu.kh/bib/ebook/storage/Network%20Security%20with%20OpenSSL.pdf (Chapater 6)

I can encrypt/decrypt successfully.

My scenario is like:

  1. Encrypt : Input plain text => encrypt with aes 256 cbc => return result in encode with base64
  2. Decrypt: Input encrypted base64 encoded string => decode base64 => decrypt with aes 256 cbc => return decrypted plain text

But i have some of the question:

  1. How to allocate the encrypted buffer size: char *out = (char *) malloc(inLength + EVP_MAX_BLOCK_LENGTH); Is this enough? I admit that i didn't goes through the detail of encryption logic even though i have some concept. If someone can give me a hint of the size of encrypted size logic, i really be appreciate. Like base64 data to data ratio is 4:3. It has 33% overhead. But for encryption, i don't find this kind of information.

  2. How to allocate the decrypted buffer size: b64decodeLen = decode b64 encrypted text. It should the original binary encrypted data length. char *out = (char *) malloc(b64decodeLen + 1);
    According to the above malloc of encrypted buffer size. I think the plain text size would be less than the binary encrypted data length. Is this right?

  3. EVP_EncryptUpdate can be called multiple times if necessary. When to call multiple times? In which case we need to call multiple times? https://stackguides.com/questions/29016193/block-cipher-in-openssl-how-to-correct-crypt-and-decrypt-in-c

while(1){
    EVP_EncryptUpdate(ctx, ciphertext + outlen_tot, &outlen, (unsigned   char*)msg + outlen_tot, block_size);
    outlen_tot += outlen;
    if( msg_len - outlen_tot < block_size ){
        break;
    }
}

In this example, it encrypt for the block_size. If i put the input string length, then i don't need to call multiple times even for every large message?

EVP_EncryptUpdate(ctx, out, &out_len, inString, strlen(inString));

Thanks a lot.

1

1 Answers

5
votes
  1. After padding and encrypting data, the size of the ciphertext is plaintext_size + (block_size - plaintext_size % block_size). So your buffer should be enough. See more here: https://en.wikipedia.org/wiki/Padding_(cryptography)
  2. You've already answered it yourself - the ratio (enc/dec) is 4:3 for base64. An exemplary code and all explanations can be found here: https://en.wikipedia.org/wiki/Base64
  3. You do multiple updates if you, for example, can't pass the whole plaintext in one run, because of some technical reasons (multiple packets, large file). Or you don't want your plaintext to linger in memory (to protect it from memory scrappers). If it's not the case for you - use single update.