1
votes

I have successfully encrypted my AES key using RSA's public key encryption. While decryption with RSA's private key I'm getting:

javax.crypto.IllegalBlockSizeException

The encryption logic that works for me is:

KeyGenerator keygen = KeyGenerator.getInstance("AES");
keygen.init(128);
SecretKey key = keygen.generateKey();
Log.d("keyS", encodeToString(key.getEncoded(), Base64.DEFAULT));
Calendar start = new GregorianCalendar();
Calendar stop = new GregorianCalendar();
stop.add(Calendar.YEAR,25);
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(Objects.requireNonNull(getContext()))
        .setKeySize(2048)
        .setAlias(KEYSTORE_PROVIDER_ANDROID_KEYSTORE)
        .setSubject(new X500Principal("CN="+KEYSTORE_PROVIDER_ANDROID_KEYSTORE))
        .setSerialNumber(BigInteger.ZERO)
        .setStartDate(start.getTime()).setEndDate(stop.getTime()).build();
KeyPairGenerator keyPairGenerator;
KeyPair kp;
keyPairGenerator = KeyPairGenerator.getInstance("RSA", KEYSTORE_PROVIDER_ANDROID_KEYSTORE);
keyPairGenerator.initialize(spec);
kp = keyPairGenerator.generateKeyPair();
Cipher cipher = Cipher.getInstance("RSA/None/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, kp.getPublic());
String key64 = encodeToString(key.getEncoded(), Base64.DEFAULT);
editor.putString(SECRET,new String(cipher.doFinal(key64.getBytes()), StandardCharsets.UTF_8)).apply();
Log.d("key2",new String(cipher.doFinal(key64.getBytes()), StandardCharsets.UTF_8));

Decryption logic I'm using currently is:

final SharedPreferences settings = getSharedPreferences(SettingsActivity.PREF_SETTINGS, MODE_PRIVATE);
KeyStore keyStore = KeyStore.getInstance(KEYSTORE_PROVIDER_ANDROID_KEYSTORE);
keyStore.load(null);
KeyStore.Entry entry = keyStore.getEntry(KEYSTORE_PROVIDER_ANDROID_KEYSTORE,null);
PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
Cipher cipher = Cipher.getInstance("RSA/None/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] tmp = Objects.requireNonNull(settings.getString(SECRET, null)).getBytes(StandardCharsets.UTF_8);
Log.d("key3",new String(tmp));
Log.d("key4", encodeToString(cipher.doFinal(tmp), Base64.DEFAULT) );

How can I fix this error that's thrown by cipher.doFinal()?

1
If you use RSA/None/NoPadding, this means that you are doing the padding. Change it to Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); - kelalaka
new String(cipher.doFinal(.. you are creating a string from non-printable characters. You should b64 encode the encrypted result before making a string from it, not the key. And indeed, please use proper padding ( RSA/ECB/OAEPWithSHA-256AndMGF1Padding or RSA/ECB/PKCS1 if the first is not available) - gusto2
RSA/ECB/OAEPWithSHA-256AndMGF1Padding shows javax.crypto.IllegalBlockSizeException - Mayank Metha

1 Answers

1
votes

Found my solution. Heres the solution. Thanks to those who help me rethink about the solution. Enciphering code:

KeyGenerator keygen = KeyGenerator.getInstance("AES");
keygen.init(128);
SecretKey key = keygen.generateKey();
Log.d("keyS", encodeToString(key.getEncoded(), Base64.DEFAULT));
Calendar start = new GregorianCalendar();
Calendar stop = new GregorianCalendar();
stop.add(Calendar.YEAR,25);
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(Objects.requireNonNull(getContext()))
                            .setKeySize(2048)
                            .setAlias(KEYSTORE_PROVIDER_ANDROID_KEYSTORE)
                            .setSubject(new X500Principal("CN="+KEYSTORE_PROVIDER_ANDROID_KEYSTORE))
                            .setSerialNumber(BigInteger.ZERO)
                            .setStartDate(start.getTime()).setEndDate(stop.getTime()).build();
KeyPairGenerator keyPairGenerator;
KeyPair kp;
keyPairGenerator = KeyPairGenerator.getInstance("RSA", KEYSTORE_PROVIDER_ANDROID_KEYSTORE);
keyPairGenerator.initialize(spec);
kp = keyPairGenerator.generateKeyPair();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, kp.getPublic());
               editor.putString(SECRET,encodeToString(cipher.doFinal(key.getEncoded()), Base64.DEFAULT)).apply();
Log.d("key2",encodeToString(cipher.doFinal(key.getEncoded()), Base64.DEFAULT));

Deciphering code:

final SharedPreferences settings = getSharedPreferences(SettingsActivity.PREF_SETTINGS, MODE_PRIVATE);
KeyStore keyStore = KeyStore.getInstance(KEYSTORE_PROVIDER_ANDROID_KEYSTORE);
keyStore.load(null);
KeyStore.Entry entry = keyStore.getEntry(KEYSTORE_PROVIDER_ANDROID_KEYSTORE,null);
PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
String k64 = Objects.requireNonNull(settings.getString(SECRET, null));
byte[] tmp = decode(k64, Base64.DEFAULT);
Log.d("key3",k64);
MainActivity.key = new SecretKeySpec(cipher.doFinal(tmp),"AES");
Log.d("key4", encodeToString(MainActivity.key.getEncoded(),Base64.DEFAULT));