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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5132939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:28:26  来源:igfitidea点击:

How to do AES decryption using OpenSSL

c++copensslaesencryption

提问by Stéphane

I'd like to use the OpenSSL library to decrypt some AES data. The code has access to the key. This project already uses libopenssl for something else, so I'd like to stick to this library.

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

I went looking directly into /usr/include/openssl/aes.hsince the OpenSSL site is light on documentation. The only decrypt function is this one:

我直接查看/usr/include/openssl/aes.h了 OpenSSL 站点的文档。唯一的解密函数是这个:

void AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);

Unfortunately, this doesn't have a way to specify the length of the inpointer, so I'm not sure how that would work.

不幸的是,这没有办法指定in指针的长度,所以我不确定它是如何工作的。

There are several other functions which I believe take a numeric parm to differentiate between encryption and decryption. For example:

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

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);

From what I understand using Google, the encparm gets set to AES_ENCRYPTor AES_DECRYPTto specify which action needs to take place.

根据我使用谷歌的理解,参数enc被设置为AES_ENCRYPTAES_DECRYPT指定需要发生的操作。

Which brings me to my 2 questions:

这让我想到了我的两个问题:

  1. What do these names mean? What is ecb, cbc, cfb128, etc..., and how do I decide which one I should be using?
  2. What is the unsigned char *ivecparm needed for most of these, and where do I get it from?
  1. 这些名字是什么意思?什么是 ecb、cbc、cfb128 等...,我该如何决定应该使用哪一种?
  2. unsigned char *ivec大多数这些需要什么参数,我从哪里得到它?

回答by sarnold

There's no size given because the block sizes for AES are fixed based on the key size; you've found the ECBmode implementation, which isn't suitable for direct use (except as a teaching tool).

没有给出大小,因为 AES 的块大小是根据密钥大小固定;您发现了ECB模式实现,它不适合直接使用(作为教学工具除外)。

ECB, CBC, CFB128, etc, are all short names for the modes of operationthat are in common use. They have different properties, but if you never touch ECB mode, you should be alright.

ECB、CBC、CFB128 等都是常用操作模式的简称。它们具有不同的属性,但是如果您从未接触过 ECB 模式,则应该没问题。

I suggest staying further away from the low-level code; use the EVP_*interfaces instead, if you can, and you can move some of these decisions into a text configuration file, so your users could easily select between the different ciphers, block sizes, and modes of operation if there should ever be a good reason to change away from the defaults.

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

My sympathies, OpenSSL documentation feels worse than it is, and it isn't that great. You may find Network Security with OpenSSLa useful book. I wish I had found it sooner the last time I needed to use OpenSSL. (Don't let the silly title fool you -- it shouldhave been titled just "OpenSSL". Oh well.)

我很同情,OpenSSL 文档感觉比实际情况更糟,而且也不是那么好。您可能会发现OpenSSL网络安全是一本很有用的书。我希望我上次需要使用 OpenSSL 时能早点找到它。(不要让愚蠢的标题愚弄你——它应该被命名为“OpenSSL”。哦,好吧。)

EditI forgot to mention the initialization vectors. They are used to make sure that if you encrypt the same data using the same key, the ciphertext won't be identical. You need the IV to decrypt the data, but you don't need to keep the IV secret. You should either generate one randomly for each session (and send it along with an RSA or El Gamal or DH-encrypted session key) or generate it identically on both endpoints, or store it locally with the file, something like that.

编辑我忘了提到初始化向量。它们用于确保如果您使用相同的密钥加密相同的数据,则密文不会相同。您需要 IV 来解密数据,但您不需要对 IV 保密。您应该为每个会话随机生成一个(并将其与 RSA 或 El Gamal 或 DH 加密的会话密钥一起发送),或者在两个端点上以相同的方式生成它,或者将其与文件一起存储在本地,诸如此类。