Reputation: 363
I'm currently working on an Java-Cyrpto-API which I want to include in an Android app later on. I tested every function of my Crypto-API and after all unit test succeeded I decided to include my jar into an Android project.
In the project I started generating a 4096-bit key pair in order to add it to an object in my class.
RSA.RSAKeyPair keyPair = null;
try {
keyPair = RSA.generateKeyPair(4096);
} catch (IOException e) {
e.printStackTrace();
}
self.setPrivateKey(keyPair.getPrivateKey());
self.setPublicKey(keyPair.getPublicKey());
Afterwards I call a function in my API which uses data from the "self" object to encrypt some data.
The app throws me the following exception when it tries to encrypt some data with RSA.
03-15 02:39:16.769 2394-2414/de.ifasec.instari E/Test﹕ javax.crypto.IllegalBlockSizeException: input must be under 512 bytes
at com.android.org.conscrypt.OpenSSLCipherRSA.engineDoFinal(OpenSSLCipherRSA.java:245)
at javax.crypto.Cipher.doFinal(Cipher.java:1340)
at com.instari.encryption.RSA.encryptWithPublic(RSA.java:91)
I used Google to find out whats going wrong here an only found posts about invalid key lengths. I used the debugger to get all keys and values I generated in the app to test them directly in my API. My API tests succeeded without any errors.
Does Android have any restrictions or problems with RSA-Encryption?
private static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";
This is my encryptWithPublic() Method:
// initialize
byte[] byteData = data.getBytes(); // convert string to byte array
PublicKey keyObject = extractPublicKey(publicKey);
// encrypt
Cipher cipher = null; // create conversion processing object
try {
cipher = Cipher.getInstance(CIPHER_ALGORITHM);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
return null;
}
cipher.init(Cipher.ENCRYPT_MODE, keyObject); // initialize object's mode and key
byte[] encryptedByteData = cipher.doFinal(byteData); // use object for encryption
return Base64.encode(encryptedByteData);
RSA.RSAKeyPair is a simple class i added to store the key:
public static class RSAKeyPair{
private String privateKey;
private String publicKey;
private RSAKeyPair(String privateKey, String publicKey) {
this.privateKey = privateKey;
this.publicKey = publicKey;
}
public String getPrivateKey() {
return privateKey;
}
public String getPublicKey() {
return publicKey;
}
}
The object self is similar to this. It just returns the keys I added before.
Upvotes: 0
Views: 2942
Reputation: 93948
It seems you are just trying to encrypt too much data. The amount of data that can be encrypted using RSA with PKCS#1 padding is the key size (512 bytes) minus the padding overhead of 11 bytes, making for a total of 501 bytes. This is true for both Android, but also for Java SE.
With Java, the "ECB"
part is a bit of a misnomer. RSA doesn't use any mode of operation, so it should have been "None"
. Only one block of plaintext will be encrypted. If you want to encrypt more, you can first generate a random AES key, use that to encrypt the message, and subsequently encrypt the random key using RSA. This is called hybrid encryption.
Upvotes: 3