RSA Android Encryption / RSA PHP Decryption

I need help to solve my problem.

Problem: I want to encrypt number (A) using the RSA public key from the Android platform, and then decrypt it on PHP Server using the private key. On each platform, I can encrypt and decrypt data (this works well), but when a PHP script tries to decrypt data encrypted from ANDROID, it will not work !!

The problem is not in the HTTP transfer, because I'm trying to decrypt directly the generating encryption from ANDROID (encoded in Base64), and it does not work at all ...

Findhere after my PHP code to decrypt data:

class MyEncryption { public $privkey = ''; public $pubkey = ''; public function __construct(){ } public function initialize() { $fp=fopen("./encryption/asasap_public.pub","r"); $temp=fread($fp,8192); fclose($fp); $this->pubkey = openssl_pkey_get_public($temp); $fp=fopen("./encryption/asasap.pem","r"); $temp=fread($fp,8192); fclose($fp); $this->privkey = openssl_get_privatekey($temp,''); } public function encrypt($data) { if (openssl_public_encrypt($data, $encrypted, $this->pubkey)) $data = base64_encode($encrypted); else throw new Exception('Unable to encrypt data. Perhaps it is bigger than the key size?'); return $data; } public function decrypt($data) { if (openssl_private_decrypt(base64_decode($data), $decrypted, $this->privkey)) $data = $decrypted; else $data = ''; return $data; } public function hex2bin($hexdata) { $bindata = ''; for ($i = 0; $i < strlen($hexdata); $i += 2) { $bindata .= chr(hexdec(substr($hexdata, $i, 2))); } return $bindata; } } 

And I use this class, like here:

 $enc = new MyEncryption(); $enc->initialize(); $data_1 = 'K27booXr0zZK4BQlI45MIPJJjPPkpCCPELGvoK/wKYUwShIWE6szlZtrmV83C5eBIrT/3lxWTH3+IOA+5mefurVUvXmQIV7fXEHNHLphyM6L9gQsMAGZMCroPjWKvJM59OMS/d5dwwhiRgzVarxXSKpxBYhEYWJTu7nRJ+bZKjumeoqnCSpmntIiV+tRYgkYflOU6j2QlesjO5tzj/TL6n7vHSO/O1qafJkzHcv8Kn2hTy+IH7QXm7z5vtjXOucHkvBm1xWORXdifh+ChyVvP16dSEmCaCAH6KqtA4viX/HwRFEi4mIWaYSIQk74NdcnQOpFcTgEu2nDwtHaBMqahw=='; $data_2 = $enc->decrypt($data_1); 3lxWTH3 + IOA + 5mefurVUvXmQIV7fXEHNHLphyM6L9gQsMAGZMCroPjWKvJM59OMS / d5dwwhiRgzVarxXSKpxBYhEYWJTu7nRJ + bZKjumeoqnCSpmntIiV + tRYgkYflOU6j2QlesjO5tzj / TL6n7vHSO / O1qafJkzHcv8Kn2hTy + IH7QXm7z5vtjXOucHkvBm1xWORXdifh + ChyVvP16dSEmCaCAH6KqtA4viX / HwRFEi4mIWaYSIQk74NdcnQOpFcTgEu2nDwtHaBMqahw =='; $enc = new MyEncryption(); $enc->initialize(); $data_1 = 'K27booXr0zZK4BQlI45MIPJJjPPkpCCPELGvoK/wKYUwShIWE6szlZtrmV83C5eBIrT/3lxWTH3+IOA+5mefurVUvXmQIV7fXEHNHLphyM6L9gQsMAGZMCroPjWKvJM59OMS/d5dwwhiRgzVarxXSKpxBYhEYWJTu7nRJ+bZKjumeoqnCSpmntIiV+tRYgkYflOU6j2QlesjO5tzj/TL6n7vHSO/O1qafJkzHcv8Kn2hTy+IH7QXm7z5vtjXOucHkvBm1xWORXdifh+ChyVvP16dSEmCaCAH6KqtA4viX/HwRFEi4mIWaYSIQk74NdcnQOpFcTgEu2nDwtHaBMqahw=='; $data_2 = $enc->decrypt($data_1); 

Here, data_1 is initialized from the encryption data (A = 5) from the android with the RSA public key (note: decryption works well on Android), but after decryption in PHP I get an empty string ...

------------------------------------------ UPDATE ---- ---

Please find here after the code for the ANDROID part:

 public byte[] encryptRSA(final InputStream publicKeyFile, String in) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { byte[] encodedKey = new byte[5000]; publicKeyFile.read(encodedKey); X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey); KeyFactory kf = KeyFactory.getInstance("RSA"); PublicKey pkPublic = kf.generatePublic(publicKeySpec); // Encrypt Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); pkCipher.init(Cipher.ENCRYPT_MODE, pkPublic); return pkCipher.doFinal(in.getBytes()); } 

After encrypting the data, I convert the byte [] to Base64 (Base64.encodeToString (input, Base64.DEFAULT)).

For the certificate I use RSA 2048 Bits envelopes in DER format for Android.

------------------------------------------ DECISION ---- ---

The error is in the following lines:

 byte[] encodedKey = new byte[5000]; publicKeyFile.read(encodedKey); 

We must read the public key exactly:

 byte[] encodedKey = new byte[/*lenght of file*/]; publicKeyFile.read(encodedKey); 
+1
source share
1 answer

There are many places where this may go wrong:

  • You transfer 5000 bytes to the X509EncodedKeySpec , most of which are 0. Are you sure you are getting the correct public key?
  • How long is the string in ?
  • String.getBytes() uses standard platform encoding and may have unintended results. Use getBytes("ASCII") or getBytes("UTF-8") .

As a rule of thumb, you should simply use SSL and not try to implement asymmetric encryption yourself.

+1
source

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


All Articles