【问题标题】:AES | Encrypt with OpenSSL, decrypt with mcryptAES |使用 OpenSSL 加密,使用 mcrypt 解密
【发布时间】:2013-08-19 11:26:50
【问题描述】:

我正在使用以下函数通过 Qt 中的 OpenSSL 库加密我的数据:

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" 在这种情况下是 "12345678901234567890123456789012abc"
"password""1hA!dh= =sJAh48S8Ak!?skiitFi120xX".

所以....如果我猜对了,那么 EVP_BytesToKey() 应该从密码中生成一个密钥,并提供数据以稍后解密字符串。

对于 Base64 编码,该密钥将是:"aQkrZD/zwMFU0VAqjYSWsrkfJfS28pQJXym20UEYNnE="
我不使用盐,所以没有 IV(应该为空)。

所以 Base64 中的 QByteArray bkey 给我留下了 "aQkrZD/zwMFU0VAqjYSWsrkfJfS28pQJXym20UEYNnE="
QByteArray bvi 给了我 Null

加密文本是“CiUqILbZo+WJBr19IiovRVc1dqGvrastwo0k67TTrs51HB8AbJe8S4uxvB2D7Dkr”

现在我正在使用以下 PHP 函数再次使用生成的密钥解密密文:

<?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;
?>

现在我希望得到类似 “12345678901234567890123456789012abc”的回复。
我得到的是“7890123456789012abc”

我的字符串似乎以正确的方式解密,但它被切成两半,只显示最后 19 个字符。 有人可以帮我吗? 我是加密新手,无法真正弄清楚我到底哪里出错了。

【问题讨论】:

标签: php qt encryption aes


【解决方案1】:

这可能是因为您的误解。你说:

我不使用盐,所以没有 IV(应该为空)。

但完全没有理由会出现这种情况。 EVP_BytesToKey 方法提供了一个密钥和一个 IV。密钥显然是正确的,但 IV 不是。这将导致纯文本中出现随机字符(IV 仅更改第一个块)。由于此块可能包含控制字符等,因此可能无法正常显示。

请记住,盐和 IV 可能有一些共同点(不应重复,可以公开等),但它们在密码学中是完全不同的概念。

请使用您的 Qt 代码再试一次,这次打印出 IV 以及密钥...

【讨论】:

  • 我所做的假设更多是因为我试图让 IV 数据失败。据我所知,IV 是一个无符号字符*。关键也是。我尝试将 IV 设为 const char*,就像我对密钥所做的那样,所以我可以把它放在一个 ByteArray 中。但是从 IV 的转换失败,之后 ByteArray 为空,所以我假设在我的情况下没有 IV。
  • 编辑:我在 Qt 中使用的方法是。 QByteArray Bkey = reinterpret_cast(key); QByteArray Biv = reinterpret_cast(iv); Bkey 包含密钥数据,而 Biv 之后为空。
  • 好的,我想我看到了问题:$iv = substr($data, 0, $ivlen);。如果您不将 IV 放在密文前面,那么您当然不应该从那里删除它。只需创建一个归零的 IV 并使用 mdecrypt_generic...中的所有数据...
  • 我删除了 substr() 并现在使用了整个数据。使用 null 的 IV 现在会给我“1²Œö)’9 Ï4Kt¾æ$‰7890123456789012abc”,当我使用归零的 IV 时,我得到“1sC@]'ö¿Š4Kt¯æ$‰7890123456789012abc”。所以它基本上把一些随机字符放在以前没有的地方。我现在也尝试了 openssl_decrypt() 而不是 mcrypt() 不幸的是,这让我遇到了完全相同的问题。 :-/
  • 你知道你在上面的代码中有一个EVP_EncryptInit_ex(&amp;en, NULL, NULL, NULL, NULL);,不是吗?
【解决方案2】:

我现在通过反复试验解决了空初始化向量的问题,尽管我不知道为什么以下是一个问题。 也许有人可以向我解释一下。

换行:int nrounds = 28; 成功了。

如果我在其中输入除 28 之外的任何其他数字,则会生成一个 IV,然后当我在 mcrypt 中使用它时,密文会以正确的方式解密。 为什么使用 openssl 函数 EVP_BytesToKey() 生成 28 轮的密钥会出现问题? 我现在将它减少到 5 轮,但我很好奇这个问题是否会再次发生在有可能生成这样一个 Null-IV 的密码轮次组合中。

不知道这个函数是怎么处理IV生成的过程的。

【讨论】:

    猜你喜欢
    • 2015-10-09
    • 2019-04-13
    • 2013-01-07
    • 2014-12-24
    • 2015-02-18
    • 2013-12-07
    • 2014-02-24
    • 2011-01-31
    • 2013-12-28
    相关资源
    最近更新 更多