Permalink
Switch branches/tags
Nothing to show
Find file Copy path
00c462c Aug 16, 2018
1 contributor

Users who have contributed to this file

185 lines (143 sloc) 12.7 KB

KeyStore

KeyStore is responsible for maintaining cryptographic keys and their owners.

and

Use the Android Keystore provider to let an individual app store its own credentials that only the app itself can access. This provides a way for apps to manage credentials that are usable only by itself while providing the same security benefits that the KeyChain API provides for system-wide credentials. This method requires no user interaction to select the credentials.

Why should I use it?

If you need to utilise and persist a cryptographic key in your application you either need to:

  1. Request some input from the user (like a password) and either use this directly to derive a key or use it to encrypt a key which can then be persisted to disk
  2. Store the key securely so it cant 'easily' be snooped

Some implementations may store a key inside shared prefs or raw on the filesystem, or worse, in the source code, which is a vulnerable approach to key management.

KeyStore allows a way to store a key in hardware (if available) or in software (as an encrypted blob based off the device lock key) making it much harder to lift keys.

This is especially handy for any kind of challenge / response auth or other process where a compromise of the key itself would cause problems.

Related API

  • KeyStore
    • KeyStore is responsible for maintaining cryptographic keys and their owners.
  • Used with
    • Cipher
      • Cipher.init(...) takes a Key which can represent a key that lives in the KeyStore
      • From J-4.3-18 this can be the output of KeyPair.getPrivate(), where KeyPair is obtained from KeyStore.getEntry(...) e.g. RSA
      • From M-6-23 this can be the output of KeyStore.getKey(..) if the Key for the passes alias is a SecretKey e.g. AES
      • KeyStore supported Cipher list is found on the Android Keystore System page
    • Key - Key is the common interface for all keys.
    • Symmetric
      • SecretKey
        • KeyStore.getEntry(alias) should return a KeyStore.SecretKeyEntry if alias represents an AES key
        • KeyStore.getKey(alias) should return a SecretKey if alias represents an AES key
      • SecretKeySpec
        • A key specification for a SecretKey and also a secret key implementation that is provider-independent. It can be used for raw secret keys that can be specified as byte[].
      • KeyGenerator
        • This class provides the public API for generating symmetric cryptographic keys.
    • Asymmetric
      • KeyPair
        • KeyPair is a container for a public key and a private key.
        • KeyStore.getEntry(..) should return a KeyStore.PrivateKeyEntry
      • KeyPairGenerator
        • KeyPairGenerator is an engine class which is capable of generating a private key and its related public key utilizing the algorithm it was initialized with.
        • KeyPairGenerator.getInstance(<cipherName>, "AndroidKeyStore"); for the key to be generated in the system keystore.
      • KeyPairGeneratorSpec
        • This provides the required parameters needed for initializing the KeyPairGenerator that works with Android KeyStore. The spec determines authorized uses of the key, such as whether user authentication is required for using the key, what operations are authorized, with what parameters, and the key's validity start and end dates
        • This class was deprecated in API level 23. Use KeyGenParameterSpec instead.
    • Both
      • KeyGenParameterSpec
        • AlgorithmParameterSpec for initializing a KeyPairGenerator or a KeyGenerator of the Android Keystore system.
        • Since M-6-23
        • More control over what the key can be used for and when
        • Supports authentication-required-before-use (lock screen | finger)

Version changes

  • D-1.6-4
    • Keystore implemented as a native keystore daemon that used a local socket as its IPC interface
  • J-4.3-18
    • Credential storage enhancements in Android 4.3
    • can store public / private keys via RSA Cipher support
    • Signiture support for RSA varients
    • can have multiple device users
      • before 4.3 only PRIMARY user could use
    • CANT store AES keys
      • but could encypt the AES key with created public / private key and in keystore
      • can store directly via hidden apis - see link above
      • Can with Vault wrapper class
    • Android 4.3 release notes
    • deamon retired and replaced with binder interface
  • K-4.4-19
    • Support for elliptic curve
    • Signiture support for ECDSA varients
  • M-6-23
    • First time for AES Cipher support (See 'Supported Algorithms')
    • KeyGenerator support for AES & HMAC
    • KeyFactory & KeyPairGenerator support for EC & RSA
    • Mac Hmac support
    • SecretKeyFactory support for AES & Hmac
    • Signature increased support
    • "Keys which do not require encryption at rest will no longer be deleted when secure lock screen is disabled or reset (for example, by the user or a Device Administrator). Keys which require encryption at rest will be deleted during these events.
    • KeyProtection
      • Specification of how a key or key pair is secured when imported into the Android Keystore system.
    • KeyStore keys can require fingerprint auth before use
      • "User authentication authorizes a specific cryptographic operation associated with one key. In this mode, each operation involving such a key must be individually authorized by the user". See api/finger for more.
  • N-7-24
  • O-8-26
    • Keymaster 3
  • P-9-28
    • Keymaster 4
    • StrongBox
    • Key importing
    • Support for 3DES encryption
    • Changes to version binding so that boot.img and system.img have separately set versions to allow for independent updates

User Authenticating Key Use

Key authentication options are below, which the api and functionality offered differ pre and post M-23-6.

Keep in mind the different modes of usage will have have an impact of the stabilty/lifecycle of the key (Android Security: The Forgetful Keystore).

OS Auth

  • OS access auth
    • Key access is tied to the apps UID
    • If rooted any user/app can in theory assume any UID
    • Access marshalled by keystore deamon on older apis and binder server on new ones

More on .setUserAuthenticationRequired(true)

If a key has been created with .setUserAuthenticationRequired(true) then the user has to either authenticate via

  • KeyGuardManager.createConfirmDeviceCredentialIntent(...) to prompt the user to enter pin, pattern or password.
    • ConfirmCredential
      • Uses .setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS)
      • This sample demonstrates how you can use device credentials (PIN, Pattern, Password) in your app to authenticate the user before they are trying to complete some actions
      • Will try to use key as part of crypto op after auth
  • Fingerprint
    • Check fingerprint.md for more. Essentially needs to perform KeyStore op in fingerprint api auth callback.

Losing Keys and how to handle

See Android Security: The Forgetful Keystore for losing Keys due to lock screen changes.

You can also lose Keys that require fingerprint auth when a new finger is enrolled. See fingerprint.md

Locking of Keystore

I have not encountered this myself but there are anecdontal reports of keystores becoming locked even when setEncryptionRequired == false. See this SO post.

Hardware vs Software & CTS

See /hardware/keystore.md

KeyMaster

The hardware KeyStore is accessed through an OEM specfific HAL. There is a softkeymaster also. See some interesting comments and links around this here.

See android.googlesource.com for keymaster code. This clone maybe easier to navigate.

CAs

CAs are also stored in the KeyStore. When added a custom CA device should prompt user to enter device credentials.

Links