Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
298 views
in Technique[技术] by (71.8m points)

php - AES | Encrypt with OpenSSL, decrypt with mcrypt

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);
}

"source" is in that case "12345678901234567890123456789012abc".
"password" is "1hA!dh==sJAh48S8Ak!?skiitFi120xX".

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: "aQkrZD/zwMFU0VAqjYSWsrkfJfS28pQJXym20UEYNnE="
I don't use a salt, so no IV (should be null).

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

The encryptet text is "CiUqILbZo+WJBr19IiovRVc1dqGvrastwo0k67TTrs51HB8AbJe8S4uxvB2D7Dkr".

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 "12345678901234567890123456789012abc".
What I get is "7890123456789012abc".

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

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

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...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...