2015-12-02 1 views
2

Я новичок в криптографии, поэтому решил создать простую программу, которая откроет файл для шифрования данных, etest.txt, затем откройте этот файл, чтобы расшифровать его и поместить в него indetest.txt.I знаю, что это звучит действительно потянуто, но его в образовательных целях. Вот мой код. Я читал много тем об этой проблеме, но никто из них не работал . мнеC: OpenSSL RSA_private_decrypt() с ошибкой: 0407A079: процедуры rsa: RSA_padding_check_PKCS1_OAEP: ошибка декодирования oaep "

#include <openssl/rsa.h> 
#include <openssl/pem.h> 
#include <openssl/err.h> 
#include <stdio.h> 
#include <string.h> 

int main(void) { 
    size_t pri_len;   // Length of private key 
    size_t pub_len;   // Length of public key 
    char *pri_key;   // Private key 
    char *pub_key;   // Public key 
    char *msg = malloc(256); // Message to encrypt 
    char *encrypt = NULL; // Encrypted message 
    char *decrypt = NULL; // Decrypted message 
    char *err;    // Buffer for any error messages 
    size_t red; 

    RSA *keypair = RSA_generate_key(2048, 3, NULL, NULL); 
    FILE *in = fopen("test.txt", "r"); 
    FILE *out = fopen("etest.txt", "w"); 

    if(in == NULL) 
    { 
     printf("in Error is %d (%s).\n", errno, strerror(errno)); 
    } 
    if(out == NULL) 
    { 
     printf("out Error is %d (%s).\n", errno, strerror(errno)); 
    } 

    encrypt = malloc(RSA_size(keypair)); 

    for(;;) 
    { 
     red = fread(msg, 1, RSA_size(keypair)-42, in); 
     if((RSA_public_encrypt(RSA_size(keypair)-42, (unsigned char*)msg, (unsigned char*)encrypt, 
              keypair, RSA_PKCS1_OAEP_PADDING)) == -1) { 
      ERR_load_crypto_strings(); 
      ERR_error_string(ERR_get_error(), err); 
      fprintf(stderr, "Error encrypting message: %s\n", err); 
     } 

     if(fwrite(encrypt, 1, strlen(encrypt), out) == 1) 
     { 
      printf("fwrite Error is %d (%s).\n", errno, strerror(errno)); 
     } 

     if(feof(in)) 
     { 
      break; 
     }  
    } 

    fclose(in); 
    fclose(out); 

    in = fopen("etest.txt", "r"); 
    out = fopen("dtest.txt", "w"); 

    if(in == NULL) 
    {   
     printf("in Error is %d (%s).\n", errno, strerror(errno)); 
    } 

    if(out == NULL) 
    {   
     printf("out Error is %d (%s).\n", errno, strerror(errno)); 
    } 

    decrypt = malloc(RSA_size(keypair)); 

    for(;;) 
    { 
     red = fread(msg, 1, 256, in); 
     if(RSA_private_decrypt(red, (unsigned char*)msg, (unsigned char*)decrypt, 
           keypair, RSA_PKCS1_OAEP_PADDING) == -1) { 

      ERR_load_crypto_strings(); 
      ERR_error_string(ERR_get_error(), err); 
      fprintf(stderr, "Error decrypting message: %s\n", err); 
     }   

     fwrite(decrypt, 1, strlen(decrypt), out); 

     if(feof(in)) 
     { 
      break; 
     } 
    } 
    fclose(in); 
    fclose(out);  
    RSA_free(keypair); 
    return 0; 
} 

Когда я запускаю код он возвращает мне ошибку говоря:... Error decrypting message: error:0407A079:rsa routines:RSA_padding_check_PKCS1_OAEP:oaep decoding error Извините, если мой вопрос звучит глупо Надеюсь, что вы можете помочь Спасибо

+0

Что вы хотите сказать? – fuz

+1

он возвращает мне ошибку. почему? – Ojs

ответ

1

Здесь несколько ошибок. Во-первых, когда вы читаете и шифрование:

red = fread(msg, 1, RSA_size(keypair)-42, in); 
if((RSA_public_encrypt(RSA_size(keypair)-42, (unsigned char*)msg, (unsigned char*)encrypt, 
            keypair, RSA_PKCS1_OAEP_PADDING)) == -1) { 

Вызов fread не обязательно читать число байтов просили, и может вернуть 0. Итак, когда вы достигнете конца файла, то человек будет шифруя больше байтов, чем вам нужно. Итак, перейдите в red для количества байтов для шифрования. Кроме того, в первую очередь проверьте, если red является 0, и если да break из цикла:

red = fread(msg, 1, RSA_size(keypair)-42, in); 
if (red == 0) break; 
if(((red=RSA_public_encrypt(RSA_size(keypair)-42, (unsigned char*)msg, (unsigned char*)encrypt, 
            keypair, RSA_PKCS1_OAEP_PADDING))) == -1) { 

Обратите внимание, что мы экономим возвращаемое значение RSA_public_encrypt. Это вступает в игру здесь, где вы пишете зашифрованные данные на диск:

if(fwrite(encrypt, 1, strlen(encrypt), out) == 1) 

encrypt представляет собой массив символов, а не строка. Это означает, что он не завершен NULL и может содержать NULL байты. Поэтому вы не можете использовать strlen. Вместо этого захватить возвращаемое значение RSA_public_encrypt и передать как размер, чтобы написать:

if(fwrite(encrypt, 1, red, out) == 1) 

Поскольку мы проверять возвращаемое значение fread, чтобы выйти из цикла, это не нужно:

if(feof(in)) 
{ 
    break; 
} 

См. this post относительно опасностей использования feof.

Тогда есть это, когда вы читаете назад зашифрованные данные:

red = fread(msg, 1, 256, in); 
if(RSA_private_decrypt(red, (unsigned char*)msg, (unsigned char*)decrypt, 
         keypair, RSA_PKCS1_OAEP_PADDING) == -1) { 

RSA_private_decrypt ожидает один зашифрованный блок, длина которого RSA_size(keypair). Поэтому читайте в том, что многие байты с диска и передают в это количество байтов функции.Кроме того, проверьте возвращаемое значение fread и break, если вы не получите ожидаемое количество, а также захватить возвращаемое значение RSA_private_decrypt:

red = fread(msg, 1, RSA_size(keypair), in); 
if (red < RSA_size(keypair)) break; 
if((red=RSA_private_decrypt(red, (unsigned char*)msg, (unsigned char*)decrypt, 
         keypair, RSA_PKCS1_OAEP_PADDING)) == -1) { 

Позже, когда вы пишете расшифрованные данные на диск:

fwrite(decrypt, 1, strlen(decrypt), out); 

Хотя то, что было расшифровано, вероятно, является строка (если ваш входной файл был обычный текст), возвращаемые данные не прекращается NULL, так явно написать, чем многие байт вместо использования strlen:

fwrite(decrypt, 1, red, out); 

Наконец, как и цикл шифрования, это не требуется в цикле дешифрования:

if(feof(in)) 
{ 
    break; 
} 

С помощью этих исправлений применяется, вы должны получить ожидаемые результаты.

+0

спасибо очень. и у меня есть дополнительный вопрос, если вы могли бы ответить. Могу ли я шифровать любой файл с этим? я имею в виду, если я использую example.jpg вместо test.txt, это сработает? – Ojs

+1

@Ojs Да, это будет работать с любым файлом, независимо от содержимого. Вот почему важно не обрабатывать данные как строки. – dbush

+0

и еще один :) :) Насколько безопасен этот алгоритм? – Ojs

Смежные вопросы