In Android, how to ensure that Private Key is stor

2019-06-24 11:18发布

问题:

KeyInfo's isInsideSecureHardware-method's return value seems to depend on device model, os version, and some other random factors.

For example when using Sony xperia z5 compact with older os version isInsideSecureHardware() could return true for some time and then suddenly start returning false for the same Private Key. With the latest os version (32.2.A.0.224) it seems to return only false. Huawei Nexus 6P returns always true.

Is there a way to make sure that the key is stored in secure hardware?

Here is my current code:

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
keyPairGenerator.initialize(new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
                                    .setUserAuthenticationRequired(true)
                                    .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
                                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                                    .build());
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// Check that private key is inside secure hardware
KeyFactory factory = KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
KeyInfo keyInfo = factory.getKeySpec(key, KeyInfo.class);
boolean secure = keyInfo.isInsideSecureHardware(); //  this usually returns false

Thanks!

Edit: In sony support forum there is a topic about the same problem: https://talk.sonymobile.com/t5/Android-development/hardware-backed-keystore/td-p/1154124

It was mentioned that following warning is printed to logs:

W keystore: Primary keymaster device failed to generate key, falling back to SW.

回答1:

According to the Android API, the only way to verify it is to first create the key then look at the information to ensure it is hardware-backed.

Looking at the specs for the phone, it was originally released on Lollipop. That was before the official Marshmallow Fingerprint API/hardware specs and manufacturers were doing their own thing. This article mentions the device you are using specifically (http://blog.elcomsoft.com/2016/06/fingerprint-unlock-security-ios-vs-google-android-part-ii/). I am wondering if whether the true values you were getting back were incorrect and then due to your O/S upgrade it fixed the logic (or broke it?). The O/S upgrade version you mention contains "1 April 2016 Google security patches"

I have a few questions:

  1. What does isUserAuthenticationRequirementEnforcedBySecureHardware() return on your device now? Is the value consistent? If it's false that could tell you that the fingerprint reader is not considered secure (or there is an O/S defect)

  2. What does older OS version mean, exactly? Lollipop? Have you tried resetting to factory defaults?