How the Android Keystore system can be secure?
Asked Answered
C

1

29

I read the Android documentation in http://developer.android.com/training/articles/keystore.html But I'm missing some details...

If an application generates a Key (symmetric or asymmetric) using AndroidKeyStore.

Can we extract the key from that keystore?

Can another application (AppB) access the key generated by AppA?

In which cases it is possible to lose the key? Device Factory reset only?

Thanks.

Casket answered 3/3, 2016 at 20:53 Comment(3)
1) you should keep your keystore safe and under no circumstances share it 2) the keys within the keystore requires a password, though I guess anything is possible, so see point 1 3) not sure I understand the question but generally I would say no, not the private key at least (used to sign the app) 4) this one I'm not sure I get either, as long as you have the keystore, you can create a signed app using it, but again. It should not be stored on device or similarVu
Thanks for your answer but I'm not speaking about the keystore that we use to sign the application. I added the Android documentation to the question.Casket
Ok then I misunderstood :-) nvmVu
C
44

You can use a normal KeyStore file or the Android KeyStore Provider.

KeyStore (API 1)

You will have to create a KeyStore file and you will also have to manage the secret to access to it. This secret is very sensitive and difficult to hide from attackers. Personally I prefer to delegate that responsibility on the Android system, and this is why I don't choose this solution over the next one.

Android KeyStore Provider (API 18)

Using this API's you will delegate all the heavy lifting of managing the file and secret on Android. You will not need to use any password since the OS itself will store it deriving from your lock screen PIN code, password, pattern and other variables.

If the device contains an embedded secure hardware, the key will be stored there (e.g., Trusted Execution Environment (TEE)). You can check KeyInfo#isInsideSecureHardware() method to see whether the key is saved there or not. This hardware mechanism provide us an extra protection in case of our app is running into a compromised Linux kernel.

Moreover, beginning with Android 9 (API level 28), StrongBox Keymaster API was introduced for those devices which include a secure chip (like Titan M on Google Pixel 3). If you're running on Android 28 or above, you just need to invoke the setIsStrongBoxBacked(boolean) method to let Android know you want to use it if it's available on the device. Even though the aforementioned TEE solution is acceptable, this mechanism of using a Secure Element (SE) is the most secure one, since it is based on a different hardware (CPU, memory, storage, etc) designed for security purposes.

Here we would have a quick example of how to create a self signed certificate and a key pair using StrongBox if supported:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")
        .apply {
            val certBuilder = KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT)
                .setKeyValidityStart(keyValidityStart)
                .setKeyValidityEnd(keyValidityEnd)
                .setCertificateSerialNumber(BigInteger.valueOf(1L))
                .setCertificateSubject(X500Principal("CN=MyCompany"))

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                initialize(
                    certBuilder
                        .setIsStrongBoxBacked(true) /* Enable StrongBox */
                        .build()
                )
            } else {
                initialize(certBuilder.build())
            }
        }
        .also {
            val keyPair = it.generateKeyPair()
            ...
        }
}

Regarding to your questions:

Can we extract the key from that KeyStore?

With both of them your app can get the PrivateKey and use it if this is what you mean.

Can another application (AppB) access the key generated by AppA?

With the KeyStore provider solution each app can only access to their KeyStore instances or aliases. Instead, using a normal KeyStore if another app has access to the file it could try to attack it.

In which case we may loose the key? Device Factory reset only?

Deleting the app will erase the KeyStore provider instance of your app. However, due to a nasty bug of Android (more common before Android 5) if the user changes the lock screen pattern into a password or just deletes the pattern, the KeyStore will be fully corrupted. The same happens when the user performs a "Clear credentials" from the Android settings. With the classic KeyStore instead, you could store it in the external storage and keep it even after a device factory reset. However, as mentioned before, it is still less secure than the provider.

I may be wrong in some aspects, but this is what I learn and I just shared my experience. Hope this is helpful for you.

Chuckwalla answered 3/3, 2016 at 21:43 Comment(3)
Thanks, it was really helpful for me.Dezhnev
@Herman : are you using Android KeyStore provider to store your keys ?Senecal
"You can get the PrivateKey" Is this true? Regarding the docs: Key material never enters the application process. When an application performs cryptographic operations using an Android Keystore key, behind the scenes plaintext, ciphertext, and messages [...] are fed to a system process which carries out the cryptographic operations.[...] the attacker may be able to use the app's keys but cannot extract their key materialMonostylous

© 2022 - 2024 — McMap. All rights reserved.