1

I want to store private key in android KeyStore, but I have problem with KeyStore.getInstance("JKS") is error like this: java.security.KeyStoreException: JKS not found.

Please help me why it's not know for this instance?

  • I have file load my keystore: mykeystore.jks

My code as below:

try {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.genKeyPair();
        X509Certificate certificate = generateCertificate(keyPair);
        KeyStore ks = KeyStore.getInstance("JKS");
        char[] password = "xxxxxx".toCharArray();
        try (FileInputStream fis = new FileInputStream("path\\mykeystore.jks")) {
            ks.load(fis, password);
        }
        Certificate[] certChain = new Certificate[1];
        certChain[0] = certificate;
        ks.setKeyEntry("key1", keyPair.getPrivate(), password, certChain);

    } catch(Exception e) {
        e.printStackTrace();
    }
  • Result error: java.security.KeyStoreException: JKS not found
BacII
  • 39
  • 1
  • 6

1 Answers1

4

A Java KeyStore (JKS) is not available on Android.

The recommended keystore on android is AndroidKeyStore. For your case, get keystore instance using AndroidKeyStore instead of JKS and set password as null because AndroidKeyStore does not accepts any password:

//...
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
//...
ks.setKeyEntry("key1", keyPair.getPrivate(), null, certChain);

In an AndroidKeyStore, you cannot set password for keys or keystore because keystore file(s) managed by Android system itself. Also, generating keys inside to the AndroidKeyStore instead of importing (eg. calling setKeyEntry) is more secure and recommended way.(In supported devices, Android generates keys in separated secure hardware. Which means, nobody, including app itself cannot export keys from that device)

So, generate keys using KeyGenParameterSpec.Builder instead of KeyPairGenerator.

You can check documentation here: https://developer.android.com/training/articles/keystore

But if you think AndroidKeyStore is still not suitable for you, you can list available keystore types in Android via:

// Iterate in security providers
for(Provider provider: Security.getProviders()) {
  for(Object item: provider.keySet()) {
    if(item.toString().startsWith("KeyStore.")) { // grep KeyStores
      Log.d(TAG, "Keystore: " + item.toString() + " available in provider: " + provider.getName());
    }
  }
}

In an Android Emulator Pixel 2 API 28 this code outputs:

Keystore: KeyStore.BouncyCastle available in provider: BC
Keystore: KeyStore.PKCS12 available in provider: BC
Keystore: KeyStore.BKS available in provider: BC
Keystore: KeyStore.AndroidCAStore available in provider: HarmonyJSSE
Keystore: KeyStore.AndroidKeyStore available in provider: AndroidKeyStore

Which means, available KeyStore's are:

BouncyCastle
PKCS12
BKS
AndroidCAStore
AndroidKeyStore
Tolga Okur
  • 6,753
  • 2
  • 20
  • 19