Android KeyStore provider

In Android 4.3, a new facility was added to allow apps to save private encryption keys in a system KeyStore . Called Android KeyStore, it restricts access only to the app that created them, and it was secured using the device pin code.

Specifically, the Android KeyStore is a certificate store, and so only public/private keys can be stored. Currently, arbitrary symmetric keys such as an AES key cannot be stored. In Android 4.4, the Elliptic Curve Digital Signature Algorithm (ECDSA) support was added to the Android KeyStore. This recipe discusses how to generate a new key, and save and fetch it from the Android KeyStore.

Getting ready

As this feature was only added in Android 4.3, ensure that the minimum SDK version in the Android manifest file is set to 18.

How to do it...

Let's get started.

  1. Create a handle on your app's KeyStore:
    public static final String ANDROID_KEYSTORE = "AndroidKeyStore";
      
      public void loadKeyStore() {
        try {
          keyStore = KeyStore.getInstance(ANDROID_KEYSTORE);
          keyStore.load(null);
        } catch (Exception e) {
          // TODO: Handle this appropriately in your app
          e.printStackTrace();
        }
      }
  2. Generate and save the app's key pair:
      public void generateNewKeyPair(String alias, Context context)
          throws Exception {
    
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        // expires 1 year from today
        end.add(1, Calendar.YEAR);
    
        KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
    .setAlias(alias)
    .setSubject(new X500Principal("CN=" + alias))
    .setSerialNumber(BigInteger.TEN)
    .setStartDate(start.getTime())
    .setEndDate(end.getTime())
    .build();
    
        // use the Android keystore
        KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA", ANDROID_KEYSTORE);
        gen.initialize(spec);
    
        // generates the keypair
        gen.generateKeyPair();
      }
  3. Retrieve the key with a given alias:
      public PrivateKey loadPrivteKey(String alias) throws Exception {
    
        if (keyStore.isKeyEntry(alias)) {
          Log.e(TAG, "Could not find key alias: " + alias);
          return null;
        }
    
        KeyStore.Entry entry = keyStore.getEntry(KEY_ALIAS, null);
    
        if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
          Log.e(TAG, " alias: " + alias + " is not a PrivateKey");
          return null;
        }
    
        return ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
      }

How it works...

The KeyStore class has been around since API level 1. To access the new Android KeyStore, you use a special constant "AndroidKeystore".

According to the Google documentation, there is a strange issue with the KeyStore class that requires you to call the load(null) method even though you are not loading the KeyStore from an input stream; otherwise, you may experience a crash.

When generating the key pair, we populate a KeyPairGeneratorSpec.Builder object with the required details—including the alias that we use to retrieve it later. In this example, we set an arbitrary validation period of 1 year from the current date and default the serial to TEN.

Loading a key from the alias is as simple as loading keyStore.getEntry("alias", null); from here, we cast to the PrivateKey interface so that we can use it in our encryption/decryption.

There's more...

The API for the KeyChain class was also updated in Android 4.3 to allow developers to determine whether the device supports hardware-backed certificate store or not. This basically means that the device supports a secure element for the certificate store. This is an exciting enhancement as it promises to keep the certificate store safe even on rooted devices. However, not all devices support this hardware feature. The LG Nexus 4, a popular device, uses ARM's TrustZone for hardware protection.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.58.122