title: RSA Publickey implemenation in android
body: <p>I have implemented RSA cryptography using in php, javascript, and android app using library:</p>
  
  <ol>
  <li><p><strong>phpseclib</strong> for php side</p></li>
  <li><p><strong>pidcrypt</strong> for javascript</p></li>
  <li><p><strong>bouncrycastle version(bcprov-jdk14-151)</strong> for anrdroid serviceprovider</p></li>
  </ol>
  
  <p>I have my cryptography mechanism like:</p>
  
  <pre><code>user-&gt;request-&gt;publickey
       -&gt;server-&gt;generate(publickey,privatekey) and save private key into Database
       -&gt;server-&gt;sendpublickey-&gt;user
       -&gt;user-&gt;encryptdata-&gt;send-&gt;server-&gt;decrypt
  </code></pre>
  
  <p>however this mechanism works fine between javascript and php encryption and decryption but in android platform when server send public key. It cannot decrypt the public key.</p>
  
  <p>now I have tested different scenario for this</p>
  
  <p>PHP KeyGenerating</p>
  
  <pre><code>$rsa = new Crypt_RSA();
  $rsa-&gt;setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
  $rsa-&gt;setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
  $rsa-&gt;setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
  define('CRYPT_RSA_EXPONENT', 65537);
  extract($rsa-&gt;createKey(1024));
  </code></pre>
  
  <p>PHP DecryptingCode</p>
  
  <pre><code>$rsa = new Crypt_RSA();
  $rsa-&gt;setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
  $rsa-&gt;setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
  $rsa-&gt;loadKey($pri);
  $binaryCiphertext=base64_decode($encrypted);
  $strBase64DecryptedData=$rsa-&gt;decrypt($binaryCiphertext);
  $plaintText = base64_decode($strBase64DecryptedData);
  </code></pre>
  
  <p>as my public key is.</p>
  
  <pre><code>-----BEGIN RSA PUBLIC KEY-----
  MIGJAoGBALrBdN8F83hT2+pBsAwiNx+v3FWp51IdEElE8UvVhfZYmePbitpzLcJi
  jZ4/tvRFXJGhqa3PKPUQkH2F4VrHruA2kNceiL/Btywc9oM+tDMeX1jcRKwXwK1k
  KdccKwn0qywG6YxQuqWQIotOfV+IIuhcHdaHBl6CZ05/cBo6AlMlAgMBAAE=
  -----END RSA PUBLIC KEY-----
  </code></pre>
  
  <ol>
  <li><p>request key from server and server generates publickey and private key and send public key <strong>MODULUS</strong> and <strong>EXPONENT</strong> to android app and apply this code:</p>
  
  <pre><code>RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(mod,exp);
  KeyFactory keyFactory = KeyFactory.getInstance("RSA","BS");
  PublicKey publicKey = keyFactory.generatePublic(rsaPublicKeySpec);
  Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BS");
  cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  byte[] encryptedBytes = cipher.doFinal(plaintText.getBytes());
  byte[] encodedBytes = org.bouncycastle.util.encoders.Base64.encode(encryptedBytes);
  String encryptedData = new String(encodedBytes);
  </code></pre></li>
  </ol>
  
  <p>this code unable to decrypt message and I get this error from PHP SIDE</p>
  
  <pre><code>Decryption error in /security/RSA.php on line **2493**
  </code></pre>
  
  <p>RSA.php 2493 code</p>
  
  <pre><code> if (ord($em[0]) != 0 || ord($em[1]) &gt; 2) {
       user_error('Decryption error');
       return false;
   }
  </code></pre>
  
  <ol start="2">
  <li><p>Second scenario is getting the publick key string and parse it</p>
  
  <pre><code>byte[] keyBytes =   Base64.decode(keyString, Base64.DEFAULT);
  String rsaPublicKeyString = new String(keyBytes); 
  String sliceKeyHeader = rsaPublicKeyString.replaceAll("(-+BEGIN RSA PUBLIC KEY-+\\r?\\n|-+END RSA PUBLICKEY-+\\r?\\n?)", "");
  byte[] encodedDER = Base64.encode(sliceKeyHeader.getBytes(),Base64.DEFAULT);
  
  X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedDER);
  KeyFactory kf = KeyFactory.getInstance("RSA","BC");
  PublicKey pkPublic = (PublicKey) kf.generatePublic(publicKeySpec);
  </code></pre></li>
  </ol>
  
  <p>with this I get error </p>
  
  <pre><code>java.security.spec.InvalidKeySpecException: 
  java.lang.ClassCastException: com.android.org.bouncycastle.asn1.DERApplicationSpecific
  cannot be cast to com.android.org.bouncycastle.asn1.ASN1Sequence
  </code></pre>
  
  <p>I know that the encoded public key is DER encoded but still i dont know what to do here
  --- I think someone can guide me with DER encode decode ---</p>
  
  <ol start="3">
  <li><p>The third scenario is</p>
  
  <pre><code> final Reader reader = new StringReader(rsaPublicKeyString);
   PemReader pemReader = new PemReader(reader);
   PemObject pemObject= pemReader.readPemObject();
   pemReader.close();
   AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(pemObject.getContent());
  </code></pre></li>
  </ol>
  
  <p>I forgot the error it was like</p>
  
  <pre><code> unable to cast pemObject to asymmetric ( not sure but something like that )
  </code></pre>
  
  <p>I even tried some of the codes from the below links but I am getting different errors.</p>
  
  <p><a href="https://stackoverflow.com/questions/7331684/rsa-android-encrypt-rsa-php-decrypt">RSA Android Encrypt / RSA PHP Decrypt</a>
  <a href="https://stackoverflow.com/questions/13229751/phpseclib-bouncycastle-rsa">PhpSeclib &lt;-&gt; BouncyCastle RSA</a></p>
  
  <p>Please look into code and help me.</p>