【问题标题】:EVP encryption core dumpedEVP 加密核心转储
【发布时间】:2018-04-16 22:45:27
【问题描述】:

我正在尝试从EVP 中解密使用AES_128_cbc() 加密的密文,密文存在于名为task3.bin 的文件中。我正在尝试进行模拟解密试验,这意味着解密未使用正确的keyiv,但长度有效。

这两个函数是从EVP的documentation page复制粘贴的,只是EVP_aes_256_cbc()改成了EVP_aes_128_cbc()作为解密方式。

void handleErrors(void) {
  ERR_print_errors_fp(stderr);
  abort();
}

int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,unsigned char *iv, unsigned char *plaintext) {
  EVP_CIPHER_CTX *ctx;

  int len;

  int plaintext_len;

  /* Create and initialise the context */
  if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

  /* Initialise the decryption operation. (changed 256 to 128 HERE!!!)*/
  if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
    handleErrors();

  /* Provide the message to be decrypted, and obtain the plaintext output.
   * EVP_DecryptUpdate can be called multiple times if necessary
   */
  if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
    handleErrors();
  plaintext_len = len;

  /* Finalise the decryption. Further plaintext bytes may be written at
   * this stage.
   */
  if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
  plaintext_len += len;

  /* Clean up */
  EVP_CIPHER_CTX_free(ctx);

  return plaintext_len;
}

这是我的 main 函数,它正在调用 decrypt

int main(void) {
  FILE *f;
  long lSize;
  char *buffer;

  char *ciphertext;
  unsigned char *iv;
  unsigned char *key;

  unsigned char decryptedtext[128];
  int decryptedtext_len;

  // read ciphertext
  f = fopen("task3.bin", "rb");
  fseek( f , 0L , SEEK_END);
  lSize = ftell( f );
  rewind( f );
  ciphertext = calloc( 1, lSize+1 );
  fread(ciphertext , lSize, 1 , f);
  fclose(f);

  // testing key and iv
  key = (unsigned char *)"0123456789012345";
  iv = (unsigned char *)"0000000000000000";

  // decrypt!
  decryptedtext_len = decrypt(ciphertext, strlen((char *)ciphertext), key, iv, decryptedtext);

  return 0;
}

我收到了错误139864800151232:error:06065064:lib(6):func(101):reason(100):evp_enc.c:529: Aborted (core dumped),我花了几个小时查看它,但没有取得多大成功。熟悉OpenSSL的人,请帮忙。


错误来自EVP_DecryptFinal_ex,最后一个EVP调用decrypt。我只能假设某些长度没有正确分配。

【问题讨论】:

  • 在任何地方都没有错误检查 - 您是否至少使用过调试器(或 printf)来查看它在崩溃前的距离?
  • 是的,我有。我已经更新了我的问题@john3136
  • EVP_DecryptFinal 调用中检查填充,查看更新的答案。
  • 此外,AES 或其他现代算法的密文本质上是随机字节值,其中可以包括 0 aka NUL,因此 使用 strlen 通常会给出错误的长度,即使存在calloc-ing(并因此归零)一个额外的字节,然后为 0。在您的示例中使用读取的长度lSize

标签: c encryption openssl


【解决方案1】:

如果您解密使用 PKCS#7 填充(通常情况)加密的数据,使用不正确的密钥解密将在大多数情况下导致填充错误。

由于填充位于最后一个块中,因此会在 EVP_DecryptFinal 调用中对其进行检查,以便一切都有意义。

根据加密算法、模式和填充量等因素,模拟解密很难甚至不可能。

注意:OpenSSL EVP 文档声明:“OpenSSL 默认使用 PKCS 填充”这是一种逃避,因为它没有声明 PKCS#5 或 PKCS#7。我必须为 AES 假设 PKCS#7。

【讨论】:

  • EVP_Encrypt/Decrypt/Cipher*EVP_CIPHER_CTX_* 的手册页的 NOTES 部分说“PKCS 填充通过添加 n 个值为 n 的填充字节来使加密数据的总长度成为块的倍数大小。即使数据已经是块大小的倍数,也总是添加填充……”这无疑是 PKCS7,即使它不使用该标签(正如我同意的那样)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-12
  • 2017-01-29
  • 2019-10-25
  • 2012-11-25
  • 2013-02-01
  • 2017-08-13
  • 2021-02-16
相关资源
最近更新 更多