Android decryption error

I am trying to encrypt and decrypt strings in an android application, but I keep getting InvalidKeyException error.

Here is my code:

// Create a key method

public void generateKeys() { Calendar cal = Calendar.getInstance(); Date now = cal.getTime(); cal.add(Calendar.YEAR, 25); Date end = cal.getTime(); KeyPairGenerator kpg = null; try { kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { e.printStackTrace(); } try { kpg.initialize(new KeyPairGeneratorSpec.Builder(context) .setAlias(KEY_ALIAS) .setStartDate(now) .setEndDate(end) .setSerialNumber(BigInteger.valueOf(1)) .setSubject(new X500Principal("CN=" + KEY_ALIAS)) .build()); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } KeyPair kp = kpg.generateKeyPair(); KeyStore ks = null; try { ks = KeyStore.getInstance("AndroidKeyStore"); ks.load(null); Enumeration<String> aliases = ks.aliases(); } catch (KeyStoreException e) { e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } KeyStore.Entry entry = null; try { entry = ks.getEntry(KEY_ALIAS, null); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnrecoverableEntryException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } if (!(entry instanceof KeyStore.PrivateKeyEntry)) { Log.e(LOG_TAG, "Not an instance of PrivateKeyEntry."); } else{ privKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); pubKey = ((KeyStore.PrivateKeyEntry) entry).getCertificate().getPublicKey(); } } 

// Encryption Method

 private String encryptString(String value){ byte[] encodedBytes = null; try { Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); encodedBytes = cipher.doFinal(value.getBytes()); } catch (Exception e) { e.printStackTrace(); } return Base64.encodeToString(encodedBytes, Base64.DEFAULT); } 

// Decryption Method

 private String decryptString(String value){ byte[] decodedBytes = null; try { Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); c.init(Cipher.DECRYPT_MODE, privKey); decodedBytes = c.doFinal(Base64.decode(value, Base64.DEFAULT)); } catch (Exception e) { e.printStackTrace(); Log.e("Error", "Error = " + e); return "SECURE_FAILURE"; } return new String(decodedBytes); } 

// Test code

  generateKeys(); String encrypted = encryptString("Hello World"); Log.e("Encrypt", "encrypted = " + encrypted); String decrypted = decryptString(encrypted); Log.e("Decrypt", "decrypted = " + decrypted); 

Encryption seems to work fine, as it outputs something like this:

encrypted = SbA2iWWKQbDL7NTA9xvtjD / viYDdpx9fLRYTSZ8UQzdBy3QLqzkswBY21ErH7FPza3vZys4E4PZw uxaGkRz0aC0FLqsYlbpcJernGm5 + D5lRcBOaZmgkNY9pMf0YP75cBbcJdcmb1rDaH40nCRDnEoXv rGESJRqT6p0NMzlZqdd9KO3tqfExwgservAWxPNtRDBbMgE4I / 09418jM5Ock5eayfOuv / STwEy6 Ecd56UjFH63h + gP6ed2aMDhBVeExMxvdloY + VnsAxS5Dkoc2GdaljtjRuPK48HQASoJK8EwAMNpz

But when I try to decrypt, I get the following error:

java.security.InvalidKeyException: need a private or public RSA key

I can’t understand why I am getting this exception? Can anyone help?

+7
java android encryption public-key-encryption private-key
source share
3 answers

Try using a different provider, for example:

 Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); 
+9
source share

this worked for me:

 private Cipher getCipher() { try { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // below android m return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); // error in android 6: InvalidKeyException: Need RSA private or public key } else { // android m and above return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); // error in android 5: NoSuchProviderException: Provider not available: AndroidKeyStoreBCWorkaround } } catch(Exception exception) { throw new RuntimeException("getCipher: Failed to get an instance of Cipher", exception); } } 
+8
source share

Deleting a statement worked for me:

 Cipher.getInstance("RSA/ECB/PKCS1Padding") 

From Java docs : "This method goes through a list of registered security providers, starting with the most preferred provider. The new encapsulating Cipher object returns an implementation of CipherSpi from the first provider that supports the specified algorithm.

+3
source share

All Articles