OpenSSL解密-EVP_DecryptFinal_ex失败

时间:2018-11-20 13:29:55

标签: c++ c c++11 openssl public-key-encryption

我正在使用此解密功能来获取使用EVP AES 265 GCM加密的密码的纯文本值;我可以在rawOut中看到数据,但是ret = EVP_DecryptFinal_ex(ctx, rawOut, &len);返回0;您能否提供有关原因的任何见解?我还看到了在rawOut + len代码中执行EVP_DecryptFinal_ex的源代码,我不确定为什么需要这样做,因为它将指针移动到缓冲区的末尾。

unsigned char* keyDecrypter(unsigned char* pszMasterKey)
{
    ERR_load_crypto_strings();

    int ret, len;
    EVP_CIPHER_CTX* ctx;
    unsigned char* rawOut = new unsigned char[48]; // ToDo Remove Hardcoded Value

    Info info = m_header.processKeyInfo();
    if (NULL == info.nonce)
        return NULL;

    if (!(ctx = EVP_CIPHER_CTX_new()))
        return NULL;

    if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, pszMasterKey, info.nonce))
        return NULL;

    if (!EVP_DecryptUpdate(ctx, NULL, &len, m_header.aad, m_header.aad_len))
        return NULL;

    if (!EVP_DecryptUpdate(ctx, rawOut, &len, m_header.encryptedValue, m_header.encryptedValueLen))
        return NULL;

    // Finalise the decryption. A positive return value indicates success,
    // anything else is a failure - the plain text is not trustworthy.
    ret = EVP_DecryptFinal_ex(ctx, rawOut, &len);

    ERR_print_errors_fp(stderr);

    EVP_CIPHER_CTX_free(ctx);

    if (ret > 0)
    {
        return rawOut;
    }
    else
    {
        return NULL;
    }
}

2 个答案:

答案 0 :(得分:0)

您需要将rawOut + len传递给EVP_DecryptFinal_ex。请参见documentation末尾的示例:

    /* Buffer passed to EVP_EncryptFinal() must be after data just
     * encrypted to avoid overwriting it.
     */
    if(!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen))
    {
         /* Error */
         return 0;
    }
    outlen += tmplen;

还要注意rawOut必须有足够的空间来容纳(m_header.aad_len + cipher_block_size)个字节。您可以使用EVP_CIPHER_block_size()获得块大小。

答案 1 :(得分:0)

来自 OpenSSL 文档:

“如果启用填充并且最终块的格式不正确,EVP_DecryptFinal() 将返回错误代码。”

显然,加密和解密之间的填充方案不匹配,或者输入解密引擎的密文大小可能与加密引擎输出的密文大小不完全匹配。请注意,密文必须包含相应调用 EVP_EncryptFinal_ex 的结果。

很遗憾,原始海报没有提供足够的信息来做出准确的判断。