title: Encrypt/Decryption RSA communication Java-PHP
body: <p>I'm trying to implement a client-server communication encrypted with RSA.
  I generate private and public key pairs in java then I pass some inputs to a PHP script through <code>GET</code> parameters. If there is only the key set as <code>GET</code> parameter the script encrypts a phrase that will be decrypted from the client (by java) otherwise if it's set a message (the m parameters see the PHP script) it should be able to decrypt it.</p>
  <p>I coded the following:</p>
  <p>java:</p>
  <pre><code>   public static void main(String[] args) throws Exception {
          // Generate public and private keys using RSA
          Map&lt;String, Object&gt; keys = getRSAKeys();
  
          PrivateKey privateKey = (PrivateKey) keys.get(&quot;private&quot;);
          PublicKey publicKey = (PublicKey) keys.get(&quot;public&quot;);
  
          StringBuilder keypublic = new StringBuilder();
  
          keypublic.append(&quot;-----BEGIN PUBLIC KEY-----\n&quot;);
          keypublic.append(Base64.getMimeEncoder().encodeToString(publicKey.getEncoded()) + &quot;\n&quot;);
          keypublic.append(&quot;-----END PUBLIC KEY-----\n&quot;);
  
          StringBuilder keyprivate = new StringBuilder();
  
          keypublic.append(&quot;-----BEGIN PRIVATE KEY-----\n&quot;);
          keypublic.append(Base64.getMimeEncoder().encodeToString(privateKey.getEncoded()) + &quot;\n&quot;);
          keypublic.append(&quot;-----END PRIVATE  KEY-----\n&quot;);
  
  
          String keyEncodedPublic = Base64.getEncoder().encodeToString(keypublic.toString().getBytes());
          String keyEncodedPrivate = Base64.getEncoder().encodeToString(keypublic.toString().getBytes());
  
          String signature = sign(&quot;MyEncryptedInternalString&quot;, privateKey);
          //Offuscare la MyEncryptedInternalString in qualche modo
          System.out.println(&quot;key: \n&quot; + Base64.getEncoder().encodeToString(signature.getBytes()) + &quot;:&quot; + 
                                                       keyEncodedPublic);
  
  
          System.out.println(&quot;\n&quot;);
  
          System.out.println(&quot;Crypted: \n&quot; +  Base64.getEncoder().encodeToString(encryptMessage(&quot;hello&quot;, privateKey).getBytes()));
          //System.out.println(&quot;Verified? &quot; + verify(&quot;test&quot;,signature,publicKey));
  
          while(true) {
  
              Scanner out = new Scanner(System.in);
              System.out.print(&quot;Insert text: &quot;);
              String enc = out.nextLine();
  
  
              String descryptedText = decryptMessage(enc, privateKey);
              System.out.println(&quot;Decrypted: &quot; + descryptedText);
              System.out.println();
  
          }
  
  
  
      }
  
  
      public static boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception {
          Signature publicSignature = Signature.getInstance(&quot;SHA256withRSA&quot;);
          publicSignature.initVerify(publicKey);
          publicSignature.update(plainText.getBytes(StandardCharsets.UTF_8));
  
          byte[] signatureBytes = Base64.getDecoder().decode(signature);
  
          return publicSignature.verify(signatureBytes);
      }
  
      public static String sign(String plainText, PrivateKey privateKey) throws Exception {
          Signature privateSignature = Signature.getInstance(&quot;SHA256withRSA&quot;);
          privateSignature.initSign(privateKey);
          privateSignature.update(plainText.getBytes(StandardCharsets.UTF_8));
  
          byte[] signature = privateSignature.sign();
  
          return Base64.getEncoder().encodeToString(signature);
      }
  
  
      // Get RSA keys. Uses key size of 2048.
      private static Map&lt;String,Object&gt; getRSAKeys() throws Exception {
          KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(&quot;RSA&quot;);
          keyPairGenerator.initialize(2048);
          KeyPair keyPair = keyPairGenerator.generateKeyPair();
          PrivateKey privateKey = keyPair.getPrivate();
          PublicKey publicKey = keyPair.getPublic();
  
          Map&lt;String, Object&gt; keys = new HashMap&lt;String,Object&gt;();
          keys.put(&quot;private&quot;, privateKey);
          keys.put(&quot;public&quot;, publicKey);
          return keys;
      }
  
      // Decrypt using RSA public key
      private static String decryptMessage(String encryptedText, PrivateKey privateKey) throws Exception {
          Cipher cipher =  Cipher.getInstance(&quot;RSA&quot;);
          cipher.init(Cipher.DECRYPT_MODE, privateKey);
          return new String(cipher.doFinal(Base64.getDecoder().decode(encryptedText)));
      }
  
  
      // Encrypt using RSA private key
      private static String encryptMessage(String plainText, PrivateKey privateKey) throws Exception {
          Cipher cipher =  Cipher.getInstance(&quot;RSA&quot;);
          cipher.init(Cipher.ENCRYPT_MODE, privateKey);
          return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes()));
      }
  </code></pre>
  <p>And the PHP script:</p>
  <pre><code>&lt;?php    
  
    function RSAEncryptMessage($string, $key){
        $data = &quot;MyEncryptedInternalString&quot;;
        $parts = explode(&quot;:&quot;,$key);
        $signature = base64_decode($parts[0]);
        $pubkeyid = $parts[1];
        $ok = openssl_verify($data, base64_decode($signature), base64_decode($pubkeyid), &quot;sha256WithRSAEncryption&quot;);
        if ($ok == 1){
            $pubkeyid = base64_decode($pubkeyid);
            openssl_public_encrypt($string, $crypted, $pubkeyid);
        }
        return base64_encode($crypted);
    }
  
    function RSADecryptMessage($string, $key){
        $data = &quot;MyEncryptedInternalString&quot;;
        $parts = explode(&quot;:&quot;,$key);
        $signature = base64_decode($parts[0]);
        $pubkeyid = $parts[1];
        //$ok = openssl_verify($data, base64_decode($signature), base64_decode($pubkeyid), &quot;sha256WithRSAEncryption&quot;);
        $pubkeyid = base64_decode($pubkeyid);
        openssl_private_decrypt(base64_decode($string), $decrypted, $pubkeyid);
        echo &quot;Decrypted text: &quot;. $decrypted;
        return $decrypted;
    }
  
    $mex = &quot;hello&quot;;
    //echo RSAEncryptMessage($m,$_GET['key']);
    if(isset($_GET['m'])){
      echo RSADecryptMessage($_GET['m'],$_GET['key']);
    }else{
      echo RSAEncryptMessage($mex,$_GET['key']);
    }
  ?&gt;
  </code></pre>
  <p>So when I try to encrypt the content by server-side and then decrypting it in Java it works correctly. I'm assuming to use the generated public key to encrypt the content (sending it to the server) and decrypting the content by using the stored private key on the client too.
  <a href="https://i.stack.imgur.com/OPREp.png" rel="nofollow noreferrer" title="Note that the encrypted string should be decrypted by the server if needed and in the screen, it has been ignored"><img src="https://i.stack.imgur.com/OPREp.png" alt="enter image description here" title="Note that the encrypted string should be decrypted by the server if needed and in the screen, it has been ignored" /></a></p>
  <p>The question:
  I'm not able to do the contrary: encrypt by client-side and decrypting by server-side using the PHP function <code>RSADecryptMessage</code>. When passing the parameters it doesn't work and writes nothing.</p>
  <p>EDIT:
  Since I need a communication both sides encrypted to avoid MITM attacks, for example, I use PUBLICKEY generated by the client, then I send the key to the server. So I encrypt my message from the server using the same public key. In this way, from the client, I'm able to decrypt the response by the server using the private key. The best way would be which server generates both public and private key pairs but unfortunately, Java is not able to decrypt a message if the key pair is generated and shared by PHP and that's why I allow the client to generate the key pair. This works. Now I need to do the contrary too, with the same public key sent previously to the server I need to decrypt a message encrypted by the client this time (in the image you can see the string &quot;crypted&quot;). Unfortunately, this seems not to work, because when I call the PHP script, the content is not decrypted.</p>