如何使用OpenSSL进行AES解密

Sté*_*ane 15 c c++ encryption 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);
Run Code Online (Sandbox Code Playgroud)

不幸的是,这没有办法指定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);
Run Code Online (Sandbox Code Playgroud)

根据我的理解,使用Google,encparm设置为AES_ENCRYPTAES_DECRYPT指定需要执行的操作.

这让我想到了两个问题:

  1. 这些名字是什么意思?什么是ecb,cbc,cfb128等...,我如何决定应该使用哪一个?
  2. unsigned char *ivec大多数这些需要什么样的parm,我从哪里得到它?

sar*_*old 18

由于AES的块大小是根据密钥大小固定的,因此没有给出大小 ; 您已经找到了ECB模式实现,它不适合直接使用(除了作为教学工具).

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

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

我的同情心,OpenSSL文档感觉比实际情况更糟糕,并不是那么好.您可能会发现使用OpenSSLNetwork Security是一本有用的书.我希望我最后一次使用OpenSSL时发现它.(不要让这个愚蠢的标题欺骗你 - 它应该只是标题为"OpenSSL".哦.好吧.)

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

  • "没有给出大小,因为AES的块大小是根据密钥大小固定的" - 不是真的; 它们固定在16个字节,与密钥大小无关.AES_decrypt不占用大小的原因是因为它只解密一个块,所以长度固定为16. (4认同)
  • @Stéphane,可惜Java默认使用ECB模式,它实际上不是针对'最终用户',而是它是最低的共同点. (2认同)