Hey,

In my app we are using RSA key, that the app generate (using android key 
store) on the first launch. From unknown reason, the app failed to 
retrieved the key from the key store on some of the devices. I've checked 
the logs, and I could not find a correlation between this bug to a specific 
OS version or to a specific device model. Also, I know for sure the app 
tried to read it only after the key created. So - my question is that: As 
far as I know, android key store should be persistent. What can cause such 
a bug?

Bellow are relevant code samples.

Key generation:

try {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", 
keyStore.getProvider());

        if (android.os.Build.VERSION.SDK_INT >= 
android.os.Build.VERSION_CODES.M){
            KeyGenParameterSpec spec;
            spec = new KeyGenParameterSpec.Builder(alias, 
KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT| 
KeyProperties.PURPOSE_SIGN| KeyProperties.PURPOSE_VERIFY)
                    .setDigests(KeyProperties.DIGEST_SHA256, 
KeyProperties.DIGEST_SHA512)
                    
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                    
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
                    .setKeySize(2048)
                    .build();

            generator.initialize(spec);
        } else {
            Calendar start = new GregorianCalendar();
            Calendar end = new GregorianCalendar();
            end.add(Calendar.YEAR, 500);

            KeyPairGeneratorSpec spec = new 
KeyPairGeneratorSpec.Builder(context)
                    .setAlias(alias)
                    .setSubject(new X500Principal("CN="+ subject))
                    .setSerialNumber(BigInteger.valueOf(new 
Random().nextInt(Integer.MAX_VALUE)))
                    .setStartDate(start.getTime())
                    .setEndDate(end.getTime())
                    .setKeySize(2048)
                    .build();

            generator.initialize(spec);
        }
        return generator.generateKeyPair();
    } catch (Exception e) {
        logger.warn("Failed to create private key in store", e);
        return null;
    }

The keystore itself intialized using the following code:

KeyStore androidKeyStore = KeyStore.getInstance("AndroidKeyStore");
            androidKeyStore.load(null);
            return androidKeyStore;

And we use the following code to retrieve the key, the bug is that on some 
devices the keystore returns null:

        try {
        Key key = keyStore.getKey(alias, null);

        if (key == null){
            logger.warn("Key not found in key store");
            return null;
        }

        if (key instanceof PrivateKey) {
            // Get certificate of public key
            Certificate cert = keyStore.getCertificate(alias);

            // Get public key
            PublicKey publicKey = cert.getPublicKey();

            // Return a key pair
            return new KeyPair(publicKey, (PrivateKey) key);
        } else {
            logger.warn("Key found, but not from current type. type found: " + 
key.getClass().getSimpleName());
        }
        return null;
    }catch (Exception e){
        logger.warn("Failed to get private key in store", e);
        return null;
    }

Question originally posted in SO:

http://stackoverflow.com/questions/37920232/android-keystore-keys-not-always-persisted


Thanks, 

Omer

-- 
You received this message because you are subscribed to the Google Groups 
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/android-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/android-developers/17cfda16-b06e-424f-b6c9-69f53113515c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to