Implementation of RSA Publickey in android

I implemented RSA cryptography using in php, javascript and android application using library:

  • phpseclib for php side

  • pidcrypt for javascript

  • version of bouncrycastle (bcprov-jdk14-151) for anrdroid serviceprovider service

I have a cryptography mechanism:

user->request->publickey ->server->generate(publickey,privatekey) and save private key into Database ->server->sendpublickey->user ->user->encryptdata->send->server->decrypt 

however, this mechanism works fine between javascript and php encryption and decryption, but on the Android platform when the server sends the public key. It cannot decrypt the public key.

now i checked a different script for this

PHP KeyGenerating

 $rsa = new Crypt_RSA(); $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1); $rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1); $rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1); define('CRYPT_RSA_EXPONENT', 65537); extract($rsa->createKey(1024)); 

PHP DecryptingCode

 $rsa = new Crypt_RSA(); $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1); $rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1); $rsa->loadKey($pri); $binaryCiphertext=base64_decode($encrypted); $strBase64DecryptedData=$rsa->decrypt($binaryCiphertext); $plaintText = base64_decode($strBase64DecryptedData); 

like my public key.

 -----BEGIN RSA PUBLIC KEY----- MIGJAoGBALrBdN8F83hT2+pBsAwiNx+v3FWp51IdEElE8UvVhfZYmePbitpzLcJi jZ4/tvRFXJGhqa3PKPUQkH2F4VrHruA2kNceiL/Btywc9oM+tDMeX1jcRKwXwK1k KdccKwn0qywG6YxQuqWQIotOfV+IIuhcHdaHBl6CZ05/cBo6AlMlAgMBAAE= -----END RSA PUBLIC KEY----- 
  • the request from the server and the server generates public and private keys and sends the MODULUS and EXPONENT public key to the Android application and applies this 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); 

this code cannot decrypt the message and I get this error from PHP SIDE

 Decryption error in /security/RSA.php on line **2493** 

RSA.php 2493 code

  if (ord($em[0]) != 0 || ord($em[1]) > 2) { user_error('Decryption error'); return false; } 
  1. The second script receives the public publication string and parses it

     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); 

with this i get an error

 java.security.spec.InvalidKeySpecException: java.lang.ClassCastException: com.android.org.bouncycastle.asn1.DERApplicationSpecific cannot be cast to com.android.org.bouncycastle.asn1.ASN1Sequence 

I know that the encoded DER public key is encoded, but still I don’t know what to do here --- I think someone can guide me with DER decoding decoding ---

  1. Third scenario

      final Reader reader = new StringReader(rsaPublicKeyString); PemReader pemReader = new PemReader(reader); PemObject pemObject= pemReader.readPemObject(); pemReader.close(); AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(pemObject.getContent()); 

I forgot the mistake as if

  unable to cast pemObject to asymmetric ( not sure but something like that ) 

I even tried some of the codes from the links below, but I get different errors.

RSA Android Encrypt / RSA PHP Decryption PhpSeclib ↔ BouncyCastle RSA

Please review the code and help me.

+6
source share
1 answer

OK After several hours of working with EXPONENT and MODULUS, I successfully encrypted and decrypted the data between the Android application and the php server, here is a solution that may become convenient for someone

my mistake was that when the encryption data is ready for encoding, I used the JAVA inner class BASE64, which generates encoded data of size x2, and php have different decoding and encoding mechanisms (I'm not very sure about this just an assumption)

to rule out that i used the apache library commons-codec-1.8 here is the correct 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(plainText.getBytes("UTF-8"));// byte[] coded = Base64.encodeBase64(encryptedBytes); //used library encode decode String encryptedData = new String(encodedBytes); 

The second last line was to encode the binary encryption data in BASE64

I will learn more about the differences between BASE64 between JAVA and PHP

thanks

+2
source

Source: https://habr.com/ru/post/975271/


All Articles