Что такое "длина" параметр AES EVP_Decrypt?

Это связано с EVP_DecryptFinal_ex Ошибка на OpenSSL

Я пытался выяснить, почему AES decrypt не работает, и наконец я нашел, в чем проблема, и теперь ищу кого-то, кто поможет мне ее решить :)

Вот код, с которым я тестировал (из разных сообщений здесь):

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>

int AES_BLOCK_SIZE = 128;

int main(int argc, char **argv)
{

  EVP_CIPHER_CTX en;
  EVP_CIPHER_CTX de;
  EVP_CIPHER_CTX_init(&en);
  EVP_CIPHER_CTX_init(&de);
  const EVP_CIPHER *cipher_type;
  unsigned char *passkey, *passiv, *plaintxt;
  char *plain;
  char *plaintext;
  unsigned char *ciphertext;
  int olen, len;
  int i =0;

  unsigned char iv[]  =          {      0x00, 0x01, 0x02, 0x03,
                                        0x04, 0x05, 0x06, 0x07,
                                        0x08, 0x09, 0x0a, 0x0b,
                                        0x0c, 0x0d, 0x0e, 0x0f,  0 };

  unsigned char key[]=      {   0x2b, 0x7e, 0x15, 0x16,
                                        0x28, 0xae, 0xd2, 0xa6,
                                        0xab, 0xf7, 0x15, 0x88,
                                        0x09, 0xcf, 0x4f, 0x3c , 0 };
 unsigned char *input = "hi this is patrick immling\n'Doctor'.\n'Doctor' who ?\nPrecisely! 123910!§$$§% !%%$&$(/=))?=(#ü++Ü**<,.here we go sometimes it i s difficult but 187! 1$5 78@2 14  .TӒ��틪�ձ1z.$�?�U���<y";

    printf("AES ALGORITHM FOR 128 bit CBC MODE\n");
    cipher_type = EVP_aes_128_cbc();
    AES_BLOCK_SIZE = 128;
    passkey = key;
    passiv = iv;
    plain = input;

    printf("iv=");
    for(i = 0; i < sizeof iv; i++){
        printf("%02x", iv[i]);
        //printf("key[%d]= %02x\n", i, key[i]);
    }
    printf("\n");
    printf("key=");
      for(i = 0; i < sizeof key; i++){
            printf("%02x", key[i]);
          //printf("key[%d]= %02x\n", i, key[i]);
      }
      printf("\n");

    printf("Initializing AES ALGORITHM FOR CBC MODE..\n");

    EVP_EncryptInit_ex(&en, cipher_type, NULL, passkey, passiv);


    EVP_DecryptInit_ex(&de, cipher_type, NULL, passkey, passiv);

    olen = len = strlen(input)+1;
    printf("len value before aes_encrypt \"%d\"\n", len);


      // max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1 bytes 
      int c_len = len + AES_BLOCK_SIZE - 1;
      int f_len = 0;
      ciphertext = (unsigned char *)malloc(c_len);

      /* allows reusing of 'e' for multiple encryption cycles */
      if(!EVP_EncryptInit_ex(&en, NULL, NULL, NULL, NULL)){
        printf("ERROR in EVP_EncryptInit_ex \n");
        return NULL;
      }

      if(!EVP_EncryptUpdate(&en, ciphertext, &c_len, plain, len)){
        printf("ERROR in EVP_EncryptUpdate \n");
        return NULL;
      }
      printf("len value after update \"%d\"\n", len);
     // printf("size of ciphertext after update \"%d\"\n", sizeof(ciphertext));
      printf("strlen value of ciphertext after update \"%d\"\n", strlen(ciphertext));

      if(!EVP_EncryptFinal_ex(&en, ciphertext+c_len, &f_len)){
        printf("ERROR in EVP_EncryptFinal_ex \n");
        return NULL;
      }
      printf("len value  after final \"%d\"\n", len);
      printf("strlen value of ciphertext after final \"%d\"\n", strlen(ciphertext));
      EVP_CIPHER_CTX_cleanup(&en);

    len = c_len + f_len;
    printf("len value after aes_encrypt \"%d\"\n", len);

//HERE IS THE PROBLEM: IF I USE len= strlen(ciphertext) I GET ERROR
    //len = strlen(ciphertext);

    printf("strlen value of ciphertext after aes_encrypt \"%d\"\n", len);

      int p_len = len;
       f_len = 0;
       plaintext = (unsigned char *)malloc(p_len);
      // memset(plaintext,0,sizeof(plaintext));
      if(!EVP_DecryptInit_ex(&de, NULL, NULL, NULL, NULL)){
        printf("ERROR in EVP_DecryptInit_ex \n");
        return NULL;
      }
      EVP_CIPHER_CTX_set_padding(&de, 0);

      if(!EVP_DecryptUpdate(&de, plaintext, &p_len, ciphertext, len)){
        printf("ERROR in EVP_DecryptUpdate\n");
        return NULL;
      }
      printf("len value after decrypt update \"%d\"\n", len);
      if(!EVP_DecryptFinal_ex(&de, plaintext+p_len, &f_len)){
        printf("ERROR in EVP_DecryptFinal_ex\n");
        ERR_print_errors_fp(stderr);
        return NULL;
      }

      EVP_CIPHER_CTX_cleanup(&de);
      len = p_len + f_len;
      printf("Decrypted value = %s\n", plaintext);

    printf("len value after aes_decrypt \"%d\"\n", len);


    if (strncmp(plaintext, input, olen))
      printf("FAIL: enc/dec failed for \"%s\"\n", input);
    else
      printf("OK: enc/dec ok for \"%s\"\n", plaintext); // \"%s\"\n
      printf("\n");

   free(ciphertext);
   free(plaintext);

  return 0;
}

Что я не понимаю:

Что я должен передать в качестве параметра "len" для процедур openSSL EVP Decrypt? Что это за волшебное len = c_len+ f_len?

Как я должен получить это в случае, если мне дадут только шифр с ключом и iv? Это ведь всегда должно быть возможно? Я знаю, что strlen - плохой параметр, особенно для двоичного кода, так как шифротекст на входе EVP Decrypt двоичный: так как же мне его получить?

Я уже вижу, что если я использую len= strlen(ciphertext), то получаю неправильный ответ, и параметр sizeof тоже не тот, так как он возвращает 4.

В stderr четко видно, что EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH, и я понимаю, как вы все указали, что данные AES должны быть 16-байтовыми кусками. Так что же я должен изменить, чтобы увеличить длину?

5
задан Community 23 May 2017 в 11:53
поделиться