Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AndroidKeystore NoSuchAlgorithm exception

I am trying to initialize a Cipher object for encryption and decryption.

String cipher = privateKey.getAlgorithm() + "/ECB/PKCS1Padding";
        mCipher = Cipher.getInstance(cipher, "AndroidKeyStore");

I keep getting the following exception on android:

    System.err: java.security.NoSuchAlgorithmException: Provider   AndroidKeyStore does not provide RSA/ECB/PKCS1Padding
   03-20 00:28:38.270 19817 21488 W System.err:     at javax.crypto.Cipher.getCipher(Cipher.java:357)
   03-20 00:28:38.270 19817 21488 W System.err:     at javax.crypto.Cipher.getInstance(Cipher.java:325)
   03-20 00:28:38.271 19817 21488 W System.err:     at javax.crypto.Cipher.getInstance(Cipher.java:297)
like image 443
user1270175 Avatar asked Mar 20 '16 07:03

user1270175


1 Answers

According to Google there is a bug in BouncyCastle that prevented them from installing their provider normally, so they used the provider name AndroidKeyStoreBCWorkaround when installing algorithms relating to AndroidKeyStore keys. See AOSP source here.

The following code will run on KitKat through Marshmallow, but I don't recommend it since Google says they will eliminate the work-around when it isn't needed any more:

Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround");

Instead use the private key to get the Cipher, the Cipher class will find the correct compatible Cipher:

KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);

KeyStore.PrivateKeyEntry keyEntry = 
        (KeyStore.PrivateKeyEntry) ks.getEntry("mykeypair", null);
PrivateKey privKey = keyEntry.getPrivateKey();

Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.ENCRYPT_MODE, privKey);
byte[] cipherText = c.doFinal(clearText, 0, clearText.length);
like image 174
satur9nine Avatar answered Sep 19 '22 04:09

satur9nine