1

I want to send large data encrypted with RSA through sockets. I use openssl and c.

Because RSA decryption is quite slow I use the common and straight forward way to encrypt the data with AES first, and afterwards I encrypt the used AES password with RSA. Then I send both, the AES encrypted data and the RSA encrypted password, through the socket and do the encryption the other way around.

I do the AES encryption with:

EVP_CIPHER_CTX en;
unsigned char password[65];
int i, x = 0;
unsigned char key[32], iv[32];
unsigned char *ciphertext;

i = dataLength + AES_BLOCK_SIZE -1;
ciphertext = (unsigned char *)malloc(i);

EVP_CIPHER_CTX_init(&en);
EVP_EncryptInit_ex(&en, EVP_aes_256_cbc(), NULL, key, iv);
EVP_EncryptUpdate(&en, ciphertext, &i, (unsigned char*)data, dataLength);
EVP_EncryptFinal_ex(&en, ciphertext+i, &x);

But how do I create the key and the iv securely? Right now I Use the following function:

EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, password, 64, 9, key, iv);

My question is: How do I create "password" correctly?

Because if I use rand() or something equal my attempt was completely useless because anybody who is able to get behind the "randomness" used for the "password" generation is able to decrypt the data anyway without caring about the RSA encryption of the "password".

Is there a function for secure passwordgeneration in openssl? Or is EVP_BytesToKey() just the wrong way to do what I want to do?

Genius
  • 569
  • 1
  • 3
  • 23
  • Take a look at how integrated encryption systems work. Shoup's [ECIES](http://www.shoup.net/papers/iso-2_1.pdf); or Abdalla, Bellare and Rogaway's [DHIES](http://charlotte.ucsd.edu/~mihir/papers/dhaes.pdf). Better, use the system rather than re-invent it. The schemes generate all the parameters, encrypt with a block cipher, add an integrity tag, and then wrap the symmetric keys using public key encryption. ECIES system wraps in elliptic curves, while DHIES uses Diffie-Hellman problem. – jww May 06 '14 at 04:45

1 Answers1

3

The default RAND_bytes method is fortunately seeded per thread, and by default uses the random number generator available from the operating system. The OpenSSL documentation seems to be out of date where Windows is involved, but you can find more information on this by looking at the answer of the venerable Thomas Pornin on security.stackoverflow.com.

EVP_BytesToKey is used to generate keys from passwords. EVP_BytesToKey is a key derivation function (KDF) that is specific to OpenSSL. OpenSSL also implements PBKDF2 which is the NIST approved method of password based key derivation function (PBKDF). But as you want a random key, not a derived key, none of those functions apply.

So please use rand(). If possible, try to check how the function is seeded for your specific platform.

Also note OpenSSL 1.1.0c changed the digest algorithm used in some internal components. Formerly, MD5 was used, and 1.1.0 switched to SHA256. Be careful the change is not affecting you in both EVP_BytesToKey and commands like openssl enc.

Community
  • 1
  • 1
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • I changed "AESKey" to "password" because it was a little misleading. Did I understand you correctly that I should use `rand()` to generate a random char password and use this password to generate the key and the iv with `EVP_BytesToKey`? – Genius Jan 21 '14 at 18:51
  • No absolutely not. Your AES key should consist only of random bytes generated using `rand()`. There seems to be no need for a password, or characters for that matter. If you use a random AES key each time you can use a static IV consisting of just zeros, otherwise it should consist of random bytes just like the key. – Maarten Bodewes Jan 21 '14 at 19:00
  • 2
    Also note that there is no such thing as an AES password. AES is a block cipher, and modern block ciphers require a key, not a password. This binary key should be indistinguishable from random. A password is not random binary data - you need some kind of conversion (a PBKDF) to convert a password to a key. Even then, a key generated from a password generally is much weaker than a fully random AES key. – Maarten Bodewes Jan 21 '14 at 19:08
  • Yes I already knew that but I thought it is the common way to generate the AES key with a password thank you for pointing that out! – Genius Jan 21 '14 at 19:12
  • 1
    Most people think that way, but fortunately only a relatively small amount of AES keys are generated from a password. They are useful for instance if you want to make a private key (e.g. a PGP key) confidential. Even then you are better off storing the key in some kind of token (e.g. a smart card). Passwords are notoriously weak for modern crypto. – Maarten Bodewes Jan 21 '14 at 19:20
  • I simply don't understand. What is the advantage of using password to generate the aes secret key. Cos no matter how secure the secret key is, if the password is stolen, the secret key is as good as useless. Cos anyone can use the stolen password to generate the secret key anyway – Nick Wills Feb 17 '22 at 20:03
  • 1
    @Bruce The idea of a password is that it cannot be stolen; it is something you can remember, and we don't know how to retrieve it from a brain other than to get it directly from the holder of the brain. If you are talking about a binary encoded value then you could steal a secret key as easily as a password, unless it is protected by some specific means. – Maarten Bodewes Feb 17 '22 at 22:29
  • Thanks for replying. So is there a need to make the password difficult to guess. E.g sometime, when we register an account to a forum, we might need to come up with a complex password such as mixture of special characters, upper and lower casing, etc., So wonder if we need to do the same for the password that generate AES keys, to prevent hacker from easily trying out all possible combinations to derive the password. – Nick Wills Feb 18 '22 at 02:21
  • The password is typically into a properties file to be used by the application to generate the AES key in order to decrypt/encrypt the sensitive data. But If i instead directly generate AES key and placed into the properties to be used by the application for decrypt/encrypt, isn't it make no difference from using the password. Although password is easy to remember, but if we put it into a properties file, then I not sure if we need to remember it. i newbie in this area, and trying to decide whether to use password-based, or directly generate AES key for my app development. – Nick Wills Feb 18 '22 at 02:30
  • Yes, **more so**. You can only perform an offline search if you get the forum's password database, otherwise you can e.g. limit the amount of tries, or put in delays etc. However, you can test offline and in parallel if you have the ciphertext. – Maarten Bodewes Feb 18 '22 at 02:30