C++ 如何使用OpenSSL进行AES解密

C++ 如何使用OpenSSL进行AES解密,c++,c,openssl,aes,encryption,C++,C,Openssl,Aes,Encryption,我想使用OpenSSL库来解密一些AES数据。代码可以访问密钥。这个项目已经将libopenssl用于其他用途,所以我想继续使用这个库 我直接查看了/usr/include/openssl/aes.h,因为openssl站点的文档很少。唯一的解密函数是: void AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); 不幸的是,这无法指定in指针的长度,因此我不确定这将如何工作 我相信还有其他

我想使用OpenSSL库来解密一些AES数据。代码可以访问密钥。这个项目已经将libopenssl用于其他用途,所以我想继续使用这个库

我直接查看了/usr/include/openssl/aes.h,因为openssl站点的文档很少。唯一的解密函数是:

void AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
不幸的是,这无法指定in指针的长度,因此我不确定这将如何工作

我相信还有其他几个函数需要一个数字参数来区分加密和解密。例如:

void AES_ecb_encrypt(*in, *out, *key, enc);
void AES_cbc_encrypt(*in, *out, length, *key, *ivec, enc);
void AES_cfb128_encrypt(*in, *out, length, *key, *ivec, *num, enc);
void AES_cfb1_encrypt(*in, *out, length, *key, *ivec, *num, enc);
void AES_cfb8_encrypt(*in, *out, length, *key, *ivec, *num, enc);
void AES_cfbr_encrypt_block(*in, *out, nbits, *key, *ivec, enc);
void AES_ofb128_encrypt(*in, *out, length, *key, *ivec, *num);
void AES_ctr128_encrypt(*in, *out, length, *key, ivec[], ecount_buf[], *num);
void AES_ige_encrypt(*in, *out, length, *key, *ivec, enc);
void AES_bi_ige_encrypt(*in, *out, length, *key, *key2, *ivec, enc);
根据我使用Google的理解,enc parm设置为AES_ENCRYPT或AES_DECRYPT,以指定需要执行的操作

这就引出了我的两个问题:

这些名字是什么意思?什么是ecb、cbc、cfb128等,我如何决定应该使用哪一种? 其中大多数需要什么样的unsigned char*ivec parm,从哪里获取?
没有给出大小,因为AES的块大小是基于密钥大小固定的;您已经找到了模式实现,它不适合直接使用,除非用作教学工具

ECB、CBC、CFB128等都是通用的缩写。它们有不同的属性,但如果你从未接触过ECB模式,你应该会没事的

我建议远离低级代码;如果可以的话,可以使用这些接口,并且可以将这些决定中的一些移动到文本配置文件中,这样用户就可以轻松地在不同的密码、块大小和操作模式之间进行选择,如果有充分的理由改变默认值的话

我的同情心是,OpenSSL文档感觉比实际情况更糟,而且也没有那么好。你可能会找到一本有用的书。我希望在我最后一次需要使用OpenSSL时能早点找到它。不要让这个愚蠢的标题愚弄你——它应该被命名为OpenSSL。哦,好吧


编辑:我忘了提那本书了。它们用于确保如果使用相同的密钥加密相同的数据,密文将不相同。你需要IV来解密数据,但你不需要保守IV的秘密。您应该为每个会话随机生成一个会话密钥,并将其与RSA或El Gamal或DH加密的会话密钥一起发送,或者在两个端点上生成相同的会话密钥,或者将其与文件一起存储在本地,诸如此类。

没有给出大小,因为AES的块大小是基于密钥大小固定的-实际上不是;它们固定为16字节,与密钥大小无关。AES_decrypt不采用大小的原因是,它只解密一个块,因此长度固定为16。请注意,如果您解密的消息是由您控制之外的另一个进程加密的,则该进程将指定块密码模式CBC、CFB等。初始化向量应该与密文一起提供。注意,当Java被告知使用AES而不指定任何其他内容时,默认为ECB模式。一旦我了解了这一点以及所有这些功能的用途,事情就变得更有意义了。我现在有了我的C/C++代码,使用OpenSSL对来自这个特定Java应用程序的有效负载进行解密。@Stéphane,可惜Java默认为ECB模式,它确实不是为“最终用户”设计的,但它是一个最低的公分母。@sarnold:我如何使用EVP_*接口进行AES加密?在你链接到的页面上,我看到很多密码,但不是AES。你不应该使用AES\u加密和朋友。您应该使用EVP_*函数。请参见OpenSSL wiki上的。事实上,您可能应该使用经过身份验证的加密,因为它同时提供机密性和真实性。请参见OpenSSL wiki上的。