title: Error using OpenSSL RSA_private_decrypt() function
body: <p>I'm trying to use the OpenSSL libraries to protect the communication between a client and a server:
  the client asks for the name, encrypts it and then sends it to the server which decrypts it. The encrypted string is correctly received by the server but when it is decrypted sometimes it works.. but sometimes I get this error</p>
  
  <blockquote>
    <p>error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02</p>
  </blockquote>
  
  <p>I found a similar question about this error and I did the suggested corrections but I still have problems because sometimes it works and sometimes not.. </p>
  
  <p>Here it is the client and server code:</p>
  
  <pre><code>    //client
  
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;string.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;netdb.h&gt;
  #include&lt;sys/time.h&gt;
  
  /*OpenSSL libraries*/
  
  #include &lt;openssl/rsa.h&gt;
  #include &lt;openssl/rand.h&gt;
  #include &lt;openssl/pem.h&gt;
  #include &lt;openssl/evp.h&gt;
  
  void generate_RSA_keys(char* public, char* private) {
  
      char file_pem[strlen(private)];
      char file_pem_pub[strlen(public)];
      strcpy(file_pem, private);
      strcpy(file_pem_pub, public);
      FILE *fp;
  
      int bits = 1024;
      unsigned long exp = RSA_F4;
      RSA *rsa;
      rsa = RSA_generate_key(bits,exp,NULL,NULL);
  
      fp = fopen(file_pem, "w");
      unsigned char *kstr = "pass";
      PEM_write_RSAPrivateKey(fp,rsa,EVP_des_ede3_cbc(),kstr,strlen(kstr),NULL,NULL);
      fclose(fp);
      fp = fopen(file_pem_pub, "w");
      PEM_write_RSAPublicKey(fp, rsa);
      fclose(fp);
      RSA_free(rsa);
  }
  
  int main(int argc, char** argv) {
  
      char nome[36];
      unsigned char* cnome;
      int sk, ret;    
      int n, nlen;
      int port;
      int rsa_size;
      struct sockaddr_in server_addr;
  
  
      if(argc != 3) {
                  fprintf(stderr, "Errore nel passaggio parametri\n");
                  exit(1);
          }
  
      //Stabilisco connessione TCP col server 
          sk = socket(AF_INET, SOCK_STREAM, 0);
          if(sk &lt; 0) {
                  perror("Client socket error!");
                  exit(1);
          }
  
      memset(&amp;server_addr, 0, sizeof(server_addr));
          port = atoi(argv[2]);
          server_addr.sin_family = AF_INET;
          server_addr.sin_port = htons(port);
          ret = inet_pton(AF_INET, "127.0.0.1", &amp;server_addr.sin_addr.s_addr);
      if(ret == -1) {
                  perror("Error");
                  exit(1);
          }
  
          ret = connect(sk, (struct sockaddr*)&amp;server_addr, sizeof(server_addr));
          if(ret == -1){
                  perror("Connection failed!");
                  exit(1);
          }
  
      printf("Connessione al server %s (porta %s) effettuata con successo\n", argv[1],
                                                          argv[2]);
  
      generate_RSA_keys("cpub.pem", "cpriv.pem");
  
      printf("Insert your name: ");
      fflush(stdout);
  
      scanf("%s", nome);
  
      //RSA ALGORITHM
  
      // Context allocation
      OpenSSL_add_all_algorithms();
      RSA* rsa = RSA_new();
  
      //Encryption
      FILE* fp;
      fp = fopen("spub.pem", "r");
  
      rsa = PEM_read_RSAPublicKey(fp, &amp;rsa, NULL, NULL);
      rsa_size = RSA_size(rsa);
  
      cnome = (unsigned char*)malloc(rsa_size);
      memset(cnome, 0 , sizeof(cnome));
  
      nlen = strlen(nome);
      RSA_public_encrypt(nlen, (const unsigned char*)nome, cnome, rsa, RSA_PKCS1_PADDING);
  
      //Context deallocation
      RSA_free(rsa);
      fclose(fp);
  
      int c_len = strlen(cnome);
      ret = send(sk, (void*)cnome, c_len+1, 0);
  
      printf("nome = %s\ncnome = %s\n", nome, cnome);
      close(sk);
      return 0;
  }
  
  
  //server
  
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;arpa/inet.h&gt;
  
  
  /*OpenSSL libraries*/
  
  #include &lt;openssl/rsa.h&gt;
  #include &lt;openssl/rand.h&gt;
  #include &lt;openssl/pem.h&gt;
  #include &lt;openssl/evp.h&gt;
  
  void generate_RSA_keys(char* public, char* private) {
  
      printf("inizio generazione chiavi\n");
      char file_pem[strlen(private)];
      char file_pem_pub[strlen(public)];
      strcpy(file_pem, private);
      strcpy(file_pem_pub, public);
      FILE *fp;
  
      int bits = 1024;
      unsigned long exp = RSA_F4;
      RSA *rsa;
      rsa = RSA_generate_key(bits,exp,NULL,NULL);
  
      fp = fopen(file_pem, "w");
      unsigned char *kstr = "pass";
      PEM_write_RSAPrivateKey(fp,rsa,EVP_des_ede3_cbc(),kstr,strlen(kstr),NULL,NULL);
      fclose(fp);
      fp = fopen(file_pem_pub, "w");
      PEM_write_RSAPublicKey(fp, rsa);
      fclose(fp);
      RSA_free(rsa);
      printf("fine generazione chiavi\n");
  }
  
  int main(int argc, char *argv[]) {
  
          //VARIABILI
          struct sockaddr_in serveraddr;
          struct sockaddr_in clientaddr;
          socklen_t addrlen;
  
      int sk;         //listening socket
          int c_sk;       //connection socket
  
      int ret, c_len;
      int rsa_size, n;
      char cnome[1024];
      char *nome;
      int yes = 1;    //per la setsockopt()
      int port;
  
      //CODICE
          if(argc != 3) {
                  fprintf(stderr, "Errore nel passaggio parametri\n");
                  exit(1);
          }
  
      if(atoi(argv[2]) &lt; 1024) {
          fprintf(stderr, "Numero di porta non valido\n");
          exit(1);
      }
  
          printf("Indirizzo: %s (Porta: %s)\n", argv[1], argv[2]);
  
      sk = socket(AF_INET, SOCK_STREAM, 0); //listening socket
          if(sk &lt; 0) {
                  perror("Server socket error!");
                  exit(1);
          }
      if(setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &amp;yes, sizeof(int)) == -1) {
                  perror("Server setsockopt error!");
                  exit(1);
          }
      memset(&amp;serveraddr, 0, sizeof(serveraddr));
          port = atoi(argv[2]);
          serveraddr.sin_family = AF_INET;
      ret = inet_pton(AF_INET, argv[1], &amp;serveraddr.sin_addr.s_addr);
          serveraddr.sin_port = htons(port);
  
      ret = bind(sk, (struct sockaddr*)&amp;serveraddr, sizeof(serveraddr));
          if(ret == -1) {
                  perror("Server bind error!");
                  exit(1);
          }
  
      ret = listen(sk, 10);
          if(ret == -1) {
                  perror("Server listen error!");
                  exit(1);
          }
  
      addrlen = sizeof(clientaddr);
  
      c_sk = accept(sk, (struct sockaddr*)&amp;clientaddr, &amp;addrlen);
          if(c_sk == -1) {
              perror("Server accept error!");
                  exit(1);
          }
  
      generate_RSA_keys("spub.pem", "spriv.pem"); 
  
      ret = recv(c_sk, (void*)cnome, sizeof(cnome), 0);
  
      //RSA ALGORITHM
      //Context allocation
      OpenSSL_add_all_algorithms();
      RSA* rsa = RSA_new();
  
      FILE* fp;
      fp = fopen("spriv.pem", "r");
  
      //Decryption
      rsa = PEM_read_RSAPrivateKey(fp, &amp;rsa, NULL, NULL);
  
      rsa_size = RSA_size(rsa);
  
      nome = (unsigned char*)malloc(rsa_size);
      memset(nome, 0, sizeof(nome));
  
      n = RSA_private_decrypt(rsa_size, (unsigned char*)cnome, nome, rsa, RSA_PKCS1_PADDING);
      char err[1024];
      ERR_load_crypto_strings();
      ERR_error_string(ERR_get_error(), err);
      fprintf(stderr, "%s\n", err);
      //Context deallocation
      RSA_free(rsa);
      fclose(fp);
  
      close(sk);
      close(c_sk);
  
      return 0;
  }
  </code></pre>