Ошибка при расшифровке знака с использованием RSA_public_decrypt, говорит, что тип блока не 01

Я пытаюсь подписать хэш открытого текста с помощью RSA-функции openssl RSA_private_encrypt. Хеш хранится в текстовом файле hash.txt, а знак хранится в sign.txt. До здесь, кажется, нет проблем. Однако, когда я расшифровываю знак с помощью RSA_public_decrypt, я получаю ошибку во время выполнения, например, такую: ошибка:0407006A: подпрограммы rsa:RSA_padding_check_PKCS1_type_1: тип блока не 01.

Ниже приведен мой код, если кто-то может, пожалуйста, взглянуть и сказать мне, что в нем не так? Мне нужно сравнить расшифрованный знак (хранящийся в dec.txt) и хэш и установить их равенство для проверки подлинности.

#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/sha.h>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>


#define KEY_LENGTH  2048
#define PUB_EXP     3
#define PRINT_KEYS
#define WRITE_TO_FILE

#define PT "A.txt"
#define HASH "hash.txt"
#define SIGN "sign.txt"
#define DEC "dec.txt"

const char* pub="public_B.pem";
const char* pri="private_B.pem";

int fileread(const char *Filename, unsigned char **input_buffer, unsigned int *size)
{
    int fd = open(Filename, O_RDONLY);
    if (fd < 0)
    {
        std::cerr << "Error in open file." << Filename <<std::endl;
        //fclose(f1);
        return 1;       
    }
    unsigned int size_temp = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET);

    *input_buffer = (unsigned char*)malloc(size_temp * sizeof(unsigned char));
    if(*input_buffer == NULL)
    {
        cerr << "Malloc failed for size for input_buffer" << size_temp*sizeof(unsigned char) << endl;
        close(fd);
        return 1;
    }

    //fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    if(size_temp != read(fd, *input_buffer, size_temp))

    {
        cerr << "Could not read input file" << errno << endl;
        free(*input_buffer);
        close(fd);
        return 1;
    }
    *size = size_temp;
    close(fd);
    return 0;
}

int filewrite( char * Filename, unsigned char *input_buffer, size_t size)
{
    int fd = open(Filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
    if (fd < 0)
    {
        cerr << "Error in open file." << Filename << errno << endl;
        //fclose(f1);
        return 1;       
    }

    //fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    if(size != write(fd, input_buffer, size))
    {
        cerr << "Could not read input file" << errno << endl;
        close(fd);
        return 1;
    }

    close(fd);
    return 0;
}

using namespace std;
int main(void) {
    size_t pri_len;            // Length of private key
    size_t pub_len;            // Length of public key
    RSA   *pri_key;           // Private key
    RSA   *pub_key;           // Public key
    char   *encrypt = NULL;    // Encrypted message
    char   *decrypt = NULL;    // Decrypted message
    char   *err;               // Buffer for any error messages

    // Generate key pair
    printf("***Reading RSA***\n\n");
    fflush(stdout);

    FILE * fp = fopen(pub,"rb");
      if(fp == NULL)
      {
          printf("Unable to open public file %s \n",pub);
          return 0;
      }
    pub_key = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL);
    fclose(fp);    

    FILE * fp2 = fopen(pri,"rb");
      if(fp2== NULL)
      {
          printf("Unable to open private file %s \n",pri);
          return 0;
      }
    pri_key = PEM_read_RSAPrivateKey(fp2, NULL, NULL, NULL);
    fclose(fp2);      

    unsigned int size; 
    unsigned char *input_buffer;
    unsigned int hsize;
    unsigned int ssize;
    unsigned int dsize;
    //Reading the input file
    int iret = fileread(PT, &input_buffer, &size);
    if (iret != 0)
    {
        std::cout << "file read fail : " << PT <<std::endl;
        free(input_buffer);
        return 1;       
    }

     cout << "Plaintext message: "<< input_buffer << endl;
     cout << "Size of plaintext message: " << size << endl;

    // terminate



        //Creating a Hash Value of the message
    unsigned char md[SHA256_DIGEST_LENGTH];
    //unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
    SHA256(input_buffer, size, (unsigned char*)&md);
    printf("Hash value:%s\n", md);

#ifdef WRITE_TO_FILE
        // Write the signed hash to a file

    hsize = sizeof(md);
    iret = filewrite(HASH, (unsigned char*)md, hsize);
    if (iret != 0)
    {
        cout << "file write fail : " << HASH << endl;
        //free(hash_buffer);
        return 1;       
    }
#endif
    cout << "Size of hash file, hash.txt = " << hsize << endl; 

    //initializing sign_buffer size
    unsigned char *sign_buffer; 
    sign_buffer = (unsigned char*)malloc(hsize*sizeof(unsigned char));
    if(NULL == sign_buffer)
    {
        cout << "Malloc failed for size for sign_buffer " << size*sizeof(unsigned char) << endl;
        free(input_buffer);
        return 1;
    }


        // Encrypt the hash value
        encrypt = (char*)malloc(RSA_size(pri_key));
        int encrypt_len;
        err = (char*)malloc(130);
        if((encrypt_len = RSA_private_encrypt(hsize, md, (unsigned char*)encrypt, pri_key, RSA_PKCS1_PADDING)) == -1) {
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
   }
    sign_buffer = (unsigned char*)encrypt;

#ifdef WRITE_TO_FILE
        // Write the signature to a file

    ssize = hsize;
    iret = filewrite(SIGN, sign_buffer, ssize);
    if (iret != 0)
    {
        cout << "file write fail : " << SIGN << endl;
        free(sign_buffer);
        return 1;       
    }
#endif

    cout << "Signed hash : " << sign_buffer << endl;
    cout << "Size of signed hash: "<< ssize << endl;    

    // Decrypt it



    unsigned char *dec_buffer;  
    dec_buffer = (unsigned char*)malloc(ssize*sizeof(unsigned char));
    if(NULL == dec_buffer)
    {
        std::cout << "Malloc failed for size for dec_buffer " << size*sizeof(unsigned char) <<std::endl;
        free(input_buffer);
        return 1;
    }

    decrypt = (char*)malloc(encrypt_len);
    //int RSA_public_decrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding);

    if(RSA_public_decrypt(ssize, sign_buffer, (unsigned char*)decrypt, pub_key, RSA_PKCS1_PADDING) == -1) {
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error decrypting message: %s\n", err);

    }
    dec_buffer = (unsigned char*)decrypt;

#ifdef WRITE_TO_FILE
    // Write the decrypted message to a file
    //initializing dec_buffer size

    dsize = ssize;
    iret = filewrite(DEC, dec_buffer, dsize);
    if (iret != 0)
    {
        cout << "file write fail : " << DEC << endl;
        free(dec_buffer);
        return 1;       
    }

    cout << "Decrypted message: " << dec_buffer << endl;    
    cout << "Size of decrypted sign = "<< dsize<< endl;

#endif

  return 0;
}

1 ответ

Эта строка не выглядит правильно:

if(RSA_public_decrypt(ssize, sign_buffer, (unsigned char*)decrypt, pub_key, RSA_PKCS1_PADDING) == -1) {

Первый аргумент должен быть длиной данных в sign_buffer что значение хранится в encrypt_len, Ты используешь ssize которая представляется длиной дайджеста до шифрования.

Другие вопросы по тегам