4

When we generate a key pair and use a private key from it in the cipher, it works as intended without any exceptions:

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
kpg.initialize(1024, new SecureRandom());
KeyPair kp = kpg.generateKeyPair();
PrivateKey privateKey = kp.getPrivate();
byte[] encryptedBytes = "SAMPLE".getBytes();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

But after saving of the generated PrivateKey into the AndroidKeyStore and extraction from it:

KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry("alias", null);
PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();

the privateKey is not null, but the same code in the first block above (for decryption) throws an exception with message "unknown key type passed to RSA" on the line:

cipher.init(Cipher.DECRYPT_MODE, privateKey);

I know that AndroidKeyStore was not purposed to extract the data about keys saved in it, but I expect it to return a correct Private Key to work with Android's Cipher class correctly at least.

Andrei K.
  • 534
  • 7
  • 20
  • How do store the key into `"AndroidKeyStore"`? May be this can be of help: https://stackoverflow.com/questions/20129130/android-keystore-how-to-save-an-rsa-privatekey – Oleg Estekhin Jun 22 '17 at 05:57
  • I know that Private Key key should be stored only with corresponding certificate and do it correctly. – Andrei K. Jun 22 '17 at 06:03
  • Just to add: the code above is actual for Android 6, on the 4.4 it throws on the same line exception: java.lang.UnsupportedOperationException: private exponent cannot be extracted. I think the possible solution will be to provide the full keystore to the cipher (as we do it for example when preparing SSLSocketFactory with KeyManagerFactory). – Andrei K. Jun 22 '17 at 07:28
  • Check this one https://stackoverflow.com/questions/20554389/android-keystore-private-exponent-cannot-be-extracted, it provides some explanation and suggests to specify the provider when creating a `Cypher` instance. – Oleg Estekhin Jun 22 '17 at 07:32
  • This solution works for 4.4, but in 6 I'm getting on the same line: java.security.InvalidKeyException: Need RSA private or public key – Andrei K. Jun 22 '17 at 07:38
  • OK, I've found a complete solution here in lanna blue's answer: https://stackoverflow.com/questions/34265943/android-decryption-error It works on all platforms (but I haven't tested it on platforms below 4.3, where AndroidKeyStore is not available at all). – Andrei K. Jun 22 '17 at 07:42
  • 1
    So much copy&paste code floating around, with no one having a clue of the how or why of anything. – President James K. Polk Jun 22 '17 at 13:01

0 Answers0