使用 AES-128/CBC 时 EVP_DecryptFinal_ex 中的间歇性解密失败

Intermittent decryption failures in EVP_DecryptFinal_ex when using AES-128/CBC

我正在使用此处找到的 EVP 库:https://www.openssl.org/docs/manmaster/crypto/EVP_EncryptInit.html

下面是我的两个加解密函数:

我正在尝试使用 AES 128 CBC 加密字符串。

字符串的格式通常为word1 word2 word3

char* encrypt(char *s, char *key) {
        unsigned char iv[16] = {[0 ... 15 ] = 0};
        unsigned char outbuf[1024] = {[0 ... 1023] = 0};
        int outlen1, outlen2;

        EVP_CIPHER_CTX ctx;

        EVP_CIPHER_CTX_init(&ctx);
        EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
        if (EVP_EncryptUpdate(&ctx, outbuf, &outlen1, s, strlen(s)) == 1) {
                if (EVP_EncryptFinal_ex(&ctx, outbuf + outlen1, &outlen2) == 1) {
                        EVP_CIPHER_CTX_cleanup(&ctx);
                        return strdup(outbuf);
                }
        }
        EVP_CIPHER_CTX_cleanup(&ctx);
        return NULL;
}

char* decrypt(char *s, char *key) {
        unsigned char iv[16] = {[0 ... 15 ] = 0};
        unsigned char outbuf[1024] = {[0 ... 1023] = 0};
        int outlen1, outlen2;

        EVP_CIPHER_CTX ctx;

        EVP_CIPHER_CTX_init(&ctx);
        EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
        if (EVP_DecryptUpdate(&ctx, outbuf, &outlen1, s, strlen(s)) == 1) {
                printf("After decrypt update\n");
                if (EVP_DecryptFinal_ex(&ctx, outbuf + outlen1, &outlen2) == 1) {
                        printf("After decrypt final\n");
                        EVP_CIPHER_CTX_cleanup(&ctx);
                        return strdup(outbuf);
                }
        }
        EVP_CIPHER_CTX_cleanup(&ctx);
        return NULL;
}

问题是解密最终函数适用于某些字符串,但不适用于其他字符串。

如果加密前的字符串类似于cat dog cow,则解密有效。

但是如果像bat dog cow,解密失败,特别是在EVP_DecryptFinal_ex()函数处。

对于某些字符串,解密总是在EVP_DecryptFinal_ex()函数处失败。它没有 return 1.

知道问题出在哪里吗?也许填充?我就是想不通。

您可能没有注意到加密字符串可能包含零字节,因此 DecryptUpdate 中的 strlen(s) 值太低。您必须从加密中记住加密数据的长度,并使用该值进行解密。