是否有可能从AES-CBC的cphertext中找出原始数据的长度

Is it possibile to find out the length of original data from a AES-CBC cphertext?

本文关键字:原始数据 cphertext 有可能 AES-CBC 是否      更新时间:2023-10-16

我正在使用VC++/OPENSSL和AES-256-CBC,我注意到由于AES是由OPENSSL自动填充的,当我尝试解密时,我得到的数据是带有填充字节的。 不仅仅是原始数据。

无论如何,是否可以在解密时获取原始数据的长度,以便我可以剪切填充字节?

这是我的代码

void Cryptology::OpenSSLAESDecodeByMapleArray(MapleByteArray& source, MapleByteArray& ba,MapleByteArray &res,bool nosalt)
{
    EVP_CIPHER_CTX de;
    unsigned int salt[] = { 56756, 352466 };
    int i, nrounds = 7;
    unsigned char key[32] = { 0 }, iv[32] = { 0 };
    if (nosalt)
    {
        i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), NULL, ba.data_ptr(), ba.GetLength(), nrounds, key, iv);
    }
    else
    {
        i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), (unsigned char *)salt, ba.data_ptr(), ba.GetLength(), nrounds, key, iv);
    }
    if (i != 32) {
        exit(0);
    }
    EVP_CIPHER_CTX_init(&de);
    EVP_DecryptInit_ex(&de, EVP_aes_256_cbc(), NULL, key, iv);

    int p_len = source.GetLength(), f_len = 0;
    unsigned char *plaintext = (unsigned char *)malloc(p_len + AES_BLOCK_SIZE);
    ZeroMemory(plaintext, p_len + AES_BLOCK_SIZE);
    EVP_DecryptInit_ex(&de, NULL, NULL, NULL, NULL);
    EVP_DecryptUpdate(&de, plaintext, &p_len, (unsigned char *)source.data_ptr(), source.GetLength());
    EVP_DecryptFinal_ex(&de, plaintext + p_len, &f_len);
    int len = p_len + f_len;

    //qDebug() << QString::number(len);
    EVP_CIPHER_CTX_cleanup(&de);

    res.fromByte((BYTE*)plaintext, p_len + AES_BLOCK_SIZE);
    ZeroMemory(plaintext, p_len + AES_BLOCK_SIZE);
    free(plaintext);
    ZeroMemory(key, 32);
    ZeroMemory(iv, 32);
    return;
}

如果启用了填充 - 则EVP_DecryptFinal(..)将验证填充,但不会在结果中返回它。那些解密的数据将比加密的数据略短。

每次调用 EVP_CipherUpdate(..)EVP_CipherFinal_ex(..)时,解密数据的实际长度在 outl 变量中返回

    int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
                         int *outl, unsigned char *in, int inl);
    int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
                          int *outl);

在代码中,len的值恰好是解密数据的长度。