I’m trying to write a simple file enc/decryption within a larger project.
I’d like to avoid libgpgme because of license issues. The openPGP standard is to complex for the project timeframe i have.
I’d like to do my encryption stuff with openssl.
Now i’ve implemented the following:
encryption (pseude code):
RAND_bytes(aes_key)
RAND_bytes(aes_salt)
EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), (const unsigned char *)aes_salt, aes_key, sizeof(aes_key), 5, key, iv);
then i aes256 my data
EVP_EncryptInit_ex(&e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
then i encrypt the key and iv with RSA
RSA_public_encrypt(flen, (unsigned char *)key, encryptedKey, rsa, RSA_PKCS1_PADDING );
RSA_public_encrypt(flen, (unsigned char *)iv, encryptedIV, rsa, RSA_PKCS1_PADDING );
then i save the 128bit key and iv at the “top” of my file (256Bytes header).
decryption:
-> read the first 256bytes (split into key and iv)
-> decrypt the key and iv with the local RSA Private Key (of course the RSA Private Key IS NOT in the file)
-> use the key and iv to decrypt the data
Am i kind of safe with that code?
Since you are using the OpenSSL envelope-encryption functions anyway, you should just directly use the
EVP_SealInit()/EVP_SealUpdate()/EVP_SealFinal()functions. These functions take care of generating the symmetric key and IV, encrypting the data with the symmetric key and encrypting the symmetric key with the recipient(s) RSA key(s).Once thing that you are not taking care of is authenticity. Under CBC mode it is possible for an attacker to make certain predictable changes to the plaintext, even if they can’t read it. To detect this, you should either calculate a HMAC over the encrypted message (using a seperate symmetric key to that used for encryption), or sign the encrypted message (eg. with
EVP_SignInit()/EVP_SignUpdate()/EVP_SignFinal()).