5

Given that there many known issues with the Android Keystore and its ability to lose data or just generally fall over (see here, here, here, here, here and here) I'm curious to know whether any developer has actually used the Android Keystore in a live app for generating keys and has not encountered a multitude of crash reports relating to the Keystore not being able to create or retrieve a key from the Keystore? How have you got around the known issues? I'm particularly interested in the scenario where the KeyPairGenerator class is used to generate a private-public key pair that does not require user authentication (i.e. doesn't require a screen lock to be set on the device).

Edit: I've included below the code that I've used for generating a private-public key pair via the Android Keystore:

KeyPair createPrivateKeyEntry(@NonNull Context context,
                              @NonNull String keyAlias) throws CryptoException {
    try {
        AlgorithmParameterSpec spec = getAlgorithmParameterSpec(context, keyAlias);

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
                "RSA",
                "AndroidKeyStore"
        );

        keyPairGenerator.initialize(spec);
        return keyPairGenerator.generateKeyPair();
    } catch (Exception e) {
        String message = "Unexpected error when attempting to create a private key entry.";
        throw new CryptoException(message, e);
    }
}

private AlgorithmParameterSpec getAlgorithmParameterSpec(@NonNull Context context,
                                                         @NonNull String keyAlias) {
    int keySize = 2048;
    X500Principal subject = new X500Principal("CN=" + keyAlias);
    BigInteger serialNumber = BigInteger.valueOf(1337);

    Calendar validityStartCalendar = Calendar.getInstance();
    Calendar validityEndCalendar = Calendar.getInstance();
    validityEndCalendar.add(Calendar.YEAR, 99);

    Date validityStartDate = validityStartCalendar.getTime();
    Date validityEndDate = validityEndCalendar.getTime();

    AlgorithmParameterSpec spec;

    if (Build.VERSION.SDK_INT >= 23) {
        spec = new KeyGenParameterSpec.Builder(keyAlias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                .setKeySize(keySize)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
                .setCertificateSubject(subject)
                .setCertificateSerialNumber(serialNumber)
                .setKeyValidityStart(validityStartDate)
                .setKeyValidityEnd(validityEndDate)
                .setUserAuthenticationRequired(false)
                .build();
    } else {
        spec = new KeyPairGeneratorSpec.Builder(context)
                .setAlias(keyAlias)
                .setKeySize(keySize)
                .setSubject(subject)
                .setSerialNumber(serialNumber)
                .setStartDate(validityStartDate)
                .setEndDate(validityEndDate)
                .build();
    }

    return spec;
}
Adil Hussain
  • 24,783
  • 20
  • 95
  • 134

0 Answers0