Othman Mohammad Othman Mohammad - 1 month ago 17
PHP Question

Decrypting a Base64 encrypted image in Android

Im trying to decrypt a text sent from the server to an android application.
On PHP, I have the following:

$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
$key = "-----BEGIN PUBLIC KEY-----\n" . ($PublicKey)
. '-----END PUBLIC KEY-----';
$rsa->loadKey($key);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
$imageEncrypt = base64_encode($rsa->encrypt($base64));


The encoding and the encryption work well.
When I send the encrypted text to android, i cannot decrypt. I used the code:

public static String decryptString(String alias,String cipherText) {
try {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
// RSAPrivateKey privateKey = (RSAPrivateKey) privateKeyEntry.getPrivateKey();

Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());

CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(Base64.decode(cipherText, Base64.DEFAULT)), output);
ArrayList<Byte> values = new ArrayList<>();
int nextByte;
while ((nextByte = cipherInputStream.read()) != -1) {
values.add((byte)nextByte);
}

byte[] bytes = new byte[values.size()];
for(int i = 0; i < bytes.length; i++) {
bytes[i] = values.get(i).byteValue();
}

String finalText = new String(bytes, 0, bytes.length, "UTF-8");
return finalText;
//decryptedText.setText(finalText);

} catch (Exception e) {
Toast.makeText(context, "Exception " + e.getMessage() + " occured", Toast.LENGTH_LONG).show();
Log.e("DecryptStringTAG", Log.getStackTraceString(e));
}
return "EMPTY";
}


The error is:

java.io.IOException: Error while finalizing cipher
Caused by: javax.crypto.IllegalBlockSizeException


The odd thing is that when i try to send from PHP a message like "Hello", android decrypts it successfully. But when i send the encrypted image, I get the stated error.

I've been struggling to find the error.

Any help?

Thanks

Answer

RSA asymmetric key encryption which is what public key encryption uses, that is RSA is essentially public key encryption. If you must use public/private key pair encryption the answer is hybrid encryption, similar to what SSL does.

Create a random symmetric key use it to encrypt the data with AES. Then encrypt the symmetric key with the RSA public key.

On decryption first decrypt the symmetric key with the RSA private key and use that to decrypt the data with the symmetric AES.

If you are looking for secure encryption you really need to get someone who is a domain expert to at least design and vett the implementation. Security is very hard to get right, if it isn't right is provides no security.