78103

AES | Encrypt with OpenSSL, decrypt with mcrypt

Question:

I am using the following function to encrypt my data via the OpenSSL Library in Qt:

QByteArray Crypto::Encrypt(QByteArray source, QString password) { EVP_CIPHER_CTX en; unsigned char *key_data; int key_data_len; QByteArray ba = password.toLatin1(); key_data = (unsigned char*)ba.data(); key_data_len = strlen((char*)key_data); int nrounds = 28; unsigned char key[32], iv[32]; EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), NULL, key_data, key_data_len, nrounds, key, iv); QByteArray bkey = reinterpret_cast<const char*>(key) //EDIT: Contains the key afterwards QByteArray biv = reinterpret_cast<const char*>(iv) //EDIT: Is Null afterwards EVP_CIPHER_CTX_init(&en); EVP_EncryptInit_ex(&en, EVP_aes_256_cbc(), NULL, key, iv); char *input = source.data(); char *out; int len = source.size(); int c_len = len + 16, f_len = 0; unsigned char *ciphertext = (unsigned char *)malloc(c_len); EVP_EncryptInit_ex(&en, NULL, NULL, NULL, NULL); EVP_EncryptUpdate(&en, ciphertext, &c_len, (unsigned char *)input, len); EVP_EncryptFinal_ex(&en, ciphertext+c_len, &f_len); len = c_len + f_len; out = (char*)ciphertext; EVP_CIPHER_CTX_cleanup(&en); return QByteArray(out, len); }

<strong>"source"</strong> is in that case <strong>"12345678901234567890123456789012abc"</strong>.<br /><strong>"password"</strong> is <strong>"1hA!dh==sJAh48S8Ak!?skiitFi120xX"</strong>.

So....if I got that right, then EVP_BytesToKey() should generate a key out of the password and supplied data to decrypt the string with later.

To Base64-Encoded that key would be: <strong>"aQkrZD/zwMFU0VAqjYSWsrkfJfS28pQJXym20UEYNnE="</strong><br /> I don't use a salt, so no IV (should be null).

So QByteArray bkey in Base64 leaves me with <strong>"aQkrZD/zwMFU0VAqjYSWsrkfJfS28pQJXym20UEYNnE="</strong><br /> QByteArray bvi is giving me <strong>Null</strong><br />

The encryptet text is <strong>"CiUqILbZo+WJBr19IiovRVc1dqGvrastwo0k67TTrs51HB8AbJe8S4uxvB2D7Dkr"</strong>.

Now I am using the following PHP function to decrypt the ciphertext with the generated key again:

<?php function decrypt_data($data, $iv, $key) { $cypher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); //if(is_null($iv)) { // $ivlen = mcrypt_enc_get_iv_size($cypher); // $iv = substr($data, 0, $ivlen); // $data = substr($data, $ivlen); //} // initialize encryption handle if (mcrypt_generic_init($cypher, $key, $iv) != -1) { // decrypt $decrypted = mdecrypt_generic($cypher, $data); // clean up mcrypt_generic_deinit($cypher); mcrypt_module_close($cypher); return $decrypted; } return false; } $ctext = "CiUqILbZo+WJBr19IiovRVc1dqGvrastwo0k67TTrs51HB8AbJe8S4uxvB2D7Dkr"; $key = "aQkrZD/zwMFU0VAqjYSWsrkfJfS28pQJXym20UEYNnE="; $res = decrypt_data(base64_decode($ctext), null, base64_decode($key)); echo $res; ?>

Now I'd expect a response like <strong>"12345678901234567890123456789012abc"</strong>.<br /> What I get is <strong>"7890123456789012abc"</strong>.

My string seems to be decrypted in the right way, but it's cut in half and only the last 19 characters are displayed. Can someone please help me with that? I'm new to encryption and can't really figure out where exactly I went wrong.

Answer1:

This is probably because of a misinterpretation from your part. You say:

<blockquote>

I don't use a salt, so no IV (should be null).

</blockquote>

But there is no reason at all why that would be the case. The EVP_BytesToKey method provided both a key and an IV. The key is obviously correct, but the IV is not. This will result in random characters in your plain text (the IV only changes the first block). As this block will likely contain control characters and what more, it may not display well.

Remember that a salt and IV may have a few things in common (should not be repeated, can be public etc.) but that they are entirely different concepts in cryptography.

Please try again with your Qt code, and this time print out the IV as well as the key...

Answer2:

I solved the problem with the empty initialisation vector by trial and error now, though I have no clue why the following was a problem at all. Maybe someone can explain that to me.

Changing the line: <strong>int nrounds = 28;</strong> did the trick.

If i put any other number than <strong>28</strong> in there, an IV is generated and when I use it afterwards in mcrypt the ciphertext is decrypted in the correct way. Why was it a problem to generate the key with <strong>28</strong> rounds with the openssl-function <strong>EVP_BytesToKey()</strong>? I reduced it to <strong>5</strong> rounds now, but I'm curious whether this problem might happen again with a password-rounds-combination that has the possibility to generate such a Null-IV.

I don't realy know how the process of the IV generation is handled in this function.

Recommend

  • Openssl/libcrypto AES 128 encoding using the KEY
  • Replace repeating delimiters in a text file with an alternate character
  • Pandas sort list of str.split()
  • spirit x3 cannot propagate attributes of type optional
  • Azure file Storage SMB slow to list files in directory
  • VB Brackets in Enum?
  • Content Provider error: bind or column index out of range: handle 0x234590
  • GHC Overlapping instances when generalising addition
  • How to dynamically configure a REST mock in SoapUi?
  • Getting an error while FTP file using FTPClient
  • python: convert string into variable name [duplicate]
  • function to check array strpos and return an array
  • python pandas-possible to compare 3 dfs of same shape using where(max())? is this a masking issue?
  • Jupyter Notebook: Import .ipynb file and access it's method in other .ipynb file giving error
  • htaccess replace character in query and redirect
  • Python : number of characters in text file
  • memcache won't store key/value because the value is too big
  • How can I declare inList constraints from a controller in Grails?
  • Recursive regex not matching template blocks
  • Override FROM image's ENV in Dockerfile
  • Strange behavior of javascript RegExp: same regular expressions produce different result [duplicate]
  • No internet connectivity inside docker container running inside kubernetes with weave as networking
  • Get row for each user where the count of a value in a column is maximum
  • No error while instantiating abstract class, even though abstract method is not implemented
  • Using extern @class in order to add a category?
  • Replace and retrieve placeholder value
  • Getting error java.io.FileNotFoundException (log4j log file) at the time of publish project on cloud
  • Setting the run time properties on SpringApplicationBuilder()
  • recyclerView does not call the onBindViewHolder when scroll in the view
  • JSON with duplicate key names losing information when parsed
  • How to make Safari send if-modified-since header?
  • How to pass list parameters for each object using Spring MVC?
  • Setting background image for body element in xhtml (for different monitors and resolutions)
  • Bitwise OR returns boolean when one of operands is nil
  • JaxB to read class hierarchy
  • Is there any way to bind data to data.frame by some index?
  • Django query for large number of relationships
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can I use `wmic` in a Windows PE script?
  • How to push additional view controllers onto NavigationController but keep the TabBar?