OpenSSL:加密解密例程的输入和输出缓冲区是否可以相同?

7

For example, in:

int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
                int *outl, unsigned char *in, int inl);

...能否使out等于in


我猜不会,但你尝试过吗?我很乐意知道。 - Francois
2个回答

6

我偶然发现了这个问题,因为我自己很好奇。由于没有人回答,我试了一下,它确实有效(至少对于AES CTR 128解密),所以我敢猜测它对其他类型也有效。以下是我的代码示例,如果你有兴趣的话。

/* Test Vector from http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors */

const unsigned char key[16] = { 0x2b, 0x7e, 0x15, 0x16,
                                0x28, 0xae, 0xd2, 0xa6,
                                0xab, 0xf7, 0x15, 0x88,
                                0x09, 0xcf, 0x4f, 0x3c };

const unsigned char IV[16] = { 0xf0, 0xf1, 0xf2, 0xf3,
                               0xf4, 0xf5, 0xf6, 0xf7,
                               0xf8, 0xf9, 0xfa, 0xfb,
                               0xfc, 0xfd, 0xfe, 0xff };

unsigned char test[16] = { 0x6b, 0xc1, 0xbe, 0xe2,
                                 0x2e, 0x40, 0x9f, 0x96,
                                 0xe9, 0x3d, 0x7e, 0x11,
                                 0x73, 0x93, 0x17, 0x2a };

EVP_CIPHER_CTX mCtx;
EVP_DecryptInit(&mCtx, EVP_aes_128_ctr(), key, IV);
int out_size;
EVP_DecryptUpdate(&mCtx, test, &out_size, test, 16);

1
我也尝试过使用加密(AES 128 CBC),它可以正常工作。 - apanloco

-2

在某些情况下,inbuf和outbuf可以写成相同的形式,但是有许多陷阱。

陷阱1:如果inbuf和outbuf写成相同的形式,在填充的情况下,你会发现输出的outlen比输入的inlen少16个字节。如果按块解析,每个块都会少16个字节,解析结果完全错误!因此,inbuf和outbuf不应该相同。

陷阱2:openssl文档明确指出EVP_DecryptUpdate的输出outbuf的长度要求为(inlen + cipher_block_size)。通常,AES的cipher_block_size为16,这意味着必须准备绑定缓冲区域的长度+准备的字节数为6。否则,将导致内存写入溢出并产生不可预测的结果。如果inbuf和outbuf使用相同的形式,则必须处理好缓冲区域长度的细节。

总之,不要将inbuf和outbuf传递到相同的位置,以免自己掉进陷阱。

---由专业翻译人员翻译。


1
请以英文撰写您的回答,因为 Stack Overflow 是一个“仅限英语”的网站。 - James Risner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接