title: Error in decrypting the sign using RSA_public_decrypt, says block type is not 01
body: <p>I'm trying to sign a hash of a plaintext message by using the openssl RSA function of RSA_private_encrypt. The hash is stored in a text file, hash.txt while the sign is stored in sign.txt. Uptil here, there appears to be no problem. However, when I decrypt the sign using RSA_public_decrypt, I get a runtime error like this - error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01. </p>
  
  <p>Below is my code, if someone could please have a look and tell me what is wrong in it? I need to compare the decrypted sign (stored in dec.txt) and hash and establish their equality to verify authentication.</p>
  
  <pre><code>#include &lt;openssl/rsa.h&gt;
  #include &lt;openssl/pem.h&gt;
  #include &lt;openssl/err.h&gt;
  #include &lt;openssl/sha.h&gt;
  #include &lt;iostream&gt;
  #include &lt;fstream&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;unistd.h&gt;
  
  
  #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 &lt; 0)
      {
          std::cerr &lt;&lt; "Error in open file." &lt;&lt; Filename &lt;&lt;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 &lt;&lt; "Malloc failed for size for input_buffer" &lt;&lt; size_temp*sizeof(unsigned char) &lt;&lt; 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 &lt;&lt; "Could not read input file" &lt;&lt; errno &lt;&lt; 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 &lt; 0)
      {
          cerr &lt;&lt; "Error in open file." &lt;&lt; Filename &lt;&lt; errno &lt;&lt; endl;
          //fclose(f1);
          return 1;       
      }
  
      //fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
      if(size != write(fd, input_buffer, size))
      {
          cerr &lt;&lt; "Could not read input file" &lt;&lt; errno &lt;&lt; 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, &amp;input_buffer, &amp;size);
      if (iret != 0)
      {
          std::cout &lt;&lt; "file read fail : " &lt;&lt; PT &lt;&lt;std::endl;
          free(input_buffer);
          return 1;       
      }
  
       cout &lt;&lt; "Plaintext message: "&lt;&lt; input_buffer &lt;&lt; endl;
       cout &lt;&lt; "Size of plaintext message: " &lt;&lt; size &lt;&lt; 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*)&amp;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 &lt;&lt; "file write fail : " &lt;&lt; HASH &lt;&lt; endl;
          //free(hash_buffer);
          return 1;       
      }
  #endif
      cout &lt;&lt; "Size of hash file, hash.txt = " &lt;&lt; hsize &lt;&lt; endl; 
  
      //initializing sign_buffer size
      unsigned char *sign_buffer; 
      sign_buffer = (unsigned char*)malloc(hsize*sizeof(unsigned char));
      if(NULL == sign_buffer)
      {
          cout &lt;&lt; "Malloc failed for size for sign_buffer " &lt;&lt; size*sizeof(unsigned char) &lt;&lt; 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 &lt;&lt; "file write fail : " &lt;&lt; SIGN &lt;&lt; endl;
          free(sign_buffer);
          return 1;       
      }
  #endif
  
      cout &lt;&lt; "Signed hash : " &lt;&lt; sign_buffer &lt;&lt; endl;
      cout &lt;&lt; "Size of signed hash: "&lt;&lt; ssize &lt;&lt; endl;    
  
      // Decrypt it
  
  
  
      unsigned char *dec_buffer;  
      dec_buffer = (unsigned char*)malloc(ssize*sizeof(unsigned char));
      if(NULL == dec_buffer)
      {
          std::cout &lt;&lt; "Malloc failed for size for dec_buffer " &lt;&lt; size*sizeof(unsigned char) &lt;&lt;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 &lt;&lt; "file write fail : " &lt;&lt; DEC &lt;&lt; endl;
          free(dec_buffer);
          return 1;       
      }
  
      cout &lt;&lt; "Decrypted message: " &lt;&lt; dec_buffer &lt;&lt; endl;    
      cout &lt;&lt; "Size of decrypted sign = "&lt;&lt; dsize&lt;&lt; endl;
  
  #endif
  
    return 0;
  }
  </code></pre>