Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Decryption Error

I am trying to encrypt and decrypt Strings in my Android application but I keep getting an InvalidKeyException error.

Here is my code:

//Generate Keys 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();
    }

}

//Encrypt 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);
}

//Decrypt 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);

It looks like the encryption works OK as it prints out 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 RSA private or public key

I can't figure why I am getting this exception? Can anyone help?

like image 402
Donal Rafferty Avatar asked Dec 14 '15 11:12

Donal Rafferty


People also ask

How do I fix encryption unsuccessful error on Android?

Despite being an indicator of a more serious underlying issue, the Encrypting Android Phone Unsuccessful problem can be solved by resetting the device to the factory settings. Flashing a new ROM is the only alternative option you have, but this process can be overwhelming for anyone who hasn't gone through it before.

What is a decryption error?

The message means that entered password does not correspond to a fingerprint stored in application storage. There might be two reasons for these issue: 1. Application has been reinstalled with a password, other then one used with previous installation to encrypt database.

What is encryption and decryption in Android?

Encryption is the process of encoding all user data on an Android device using symmetric encryption keys. Once a device is encrypted, all user-created data is automatically encrypted before committing it to disk and all reads automatically decrypt data before returning it to the calling process.


2 Answers

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);
    }
}
like image 89
lanna blue Avatar answered Oct 07 '22 22:10

lanna blue


Try using a different provider, like this:

Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround");
like image 31
Luis Avatar answered Oct 07 '22 20:10

Luis