如何使用 OpenSSL 进行 AES 解密
我想使用 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
参数设置为 AES_ENCRYPT
或 AES_DECRYPT
来指定需要执行哪个操作。
这让我想到了两个问题:
- 这些名字的含义是什么?什么是 ecb、cbc、cfb128 等...,我如何决定应该使用哪一个?
- 其中大多数所需的
unsigned char *ivec
参数是什么?我从哪里获取它?
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.
I went looking directly into /usr/include/openssl/aes.h
since the OpenSSL site is light on documentation. The only decrypt function is this one:
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 in
pointer, so I'm not sure how that would work.
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 enc
parm gets set to AES_ENCRYPT
or AES_DECRYPT
to specify which action needs to take place.
Which brings me to my 2 questions:
- What do these names mean? What is ecb, cbc, cfb128, etc..., and how do I decide which one I should be using?
- What is the
unsigned char *ivec
parm needed for most of these, and where do I get it from?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
没有给出大小,因为 AES 的块大小是固定的
基于密钥大小;您已经找到了 ECB 模式实现,它不适合直接使用(除非教学工具)。ECB、CBC、CFB128 等都是常用的操作模式的简称。它们具有不同的属性,但如果您从未接触过 ECB 模式,应该没问题。
我建议远离底层代码;如果可以的话,请使用
EVP_*
接口将其中一些决策移至文本配置文件中,以便您的用户可以轻松地在不同的密码、块大小和操作模式之间进行选择(如果有充分的理由更改默认设置)。我很同情 OpenSSL 文档,感觉比实际情况更糟糕,而且也不是那么好。您可能会发现OpenSSL 的网络安全一本有用的书。我希望上次需要使用 OpenSSL 时能早点找到它。 (不要让这个愚蠢的标题欺骗了您——它应该的标题只是“OpenSSL”。哦,好吧。)
编辑我忘了提及初始化向量。它们用于确保如果使用相同的密钥加密相同的数据,密文不会相同。您需要 IV 来解密数据,但不需要对 IV 保密。您应该为每个会话随机生成一个(并将其与 RSA 或 El Gamal 或 DH 加密的会话密钥一起发送),或者在两个端点上以相同的方式生成它,或者将其与文件一起存储在本地,类似这样。
There's no size given because the block sizes for AES are fixed
based on the key size; you've found the ECB mode implementation, which isn't suitable for direct use (except as a teaching tool).ECB, CBC, CFB128, etc, are all short names for the modes of operation that are in common use. They have different properties, but if you never touch ECB mode, you should be alright.
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.My sympathies, OpenSSL documentation feels worse than it is, and it isn't that great. You may find Network Security with OpenSSL a 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 should have been titled just "OpenSSL". Oh well.)
Edit I 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.