在硬件支持的android密钥库中创建密钥对

时间:2017-02-15 08:12:20

标签: android

我正在使用samsung galaxy s7并检查它支持硬件支持的密钥库。 (设置 - >安全 - >凭据存储 - >存储类型)

然后,我尝试生成一个新的私钥并使用KeyInfo的isInsideSecureHardware进行检查,但它返回false。我发现在'/ data / misc / keystore / user_0 /'目录下生成了一组与密钥库相关的文件。

为什么密钥没有存储在硬件(TEE)中?以及如何在硬件安全密钥库中生成密钥?

这是我的代码:

KeyPairGenerator kpg = KeyPairGenerator.getInstance(this.algorithm, "AndroidKeyStore");
Builder kpgparams = (new Builder(keyname, 6)).setAlgorithmParameterSpec(new ECGenParameterSpec(this.curve)).setDigests(new String[]{"SHA-256"}).setUserAuthenticationRequired(false).setUserAuthenticationValidityDurationSeconds(300);
kpg.initialize(kpgparams.build());
KeyPair kp = kpg.generateKeyPair();
:
KeyFactory factory = KeyFactory.getInstance(privateKey.getAlgorithm(), "AndroidKeyStore");
KeyInfo keyInfo = factory.getKeySpec(privateKey, KeyInfo.class);
boolean secure = keyInfo.isInsideSecureHardware();

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我可以看到有关创建密钥的方式的差异。我已经创建了如下密钥。

public static boolean createKey(Context context) {
    try {
        // Create new key if needed
        if (!isKeyPresent()) {
            Log.d(TAG, "Creating new KEY. KEY ALIAS NOT FOUND");
            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            end.add(Calendar.YEAR, 10);
            KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
                    .setAlias(KEY_ALIAS)
                    .setSubject(new X500Principal("CN=" + KEY_ALIAS + ", O=Android Authority"))
                    .setSerialNumber(BigInteger.ONE)
                    .setStartDate(start.getTime())
                    .setEndDate(end.getTime())
                    .build();
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", KEYSTORE_TYPE);
            generator.initialize(spec);
            generator.generateKeyPair();
            return true;
        } else {
            Log.d(TAG, "KEY ALIAS Exists");
            return false;
        }

    } catch (Exception e) {
        Log.e(TAG, Log.getStackTraceString(e));
    }
    return false;
}

然后验证设备是否具有如下所示的硬件支持的密钥库。

public static boolean isHardwareBackedKeyStore() {
    if (android.os.Build.VERSION.SDK_INT < 23) {
        return KeyChain.isBoundKeyAlgorithm(KeyProperties.KEY_ALGORITHM_RSA);
    } else {
        try {
            KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
            keyStore.load(null);
            PrivateKey privateKey = (PrivateKey) keyStore.getKey(KEY_ALIAS, null);
            KeyFactory keyFactory = KeyFactory.getInstance(privateKey.getAlgorithm(), "AndroidKeyStore");
            KeyInfo keyInfo = keyFactory.getKeySpec(privateKey, KeyInfo.class);
            return keyInfo.isInsideSecureHardware();
        } catch (Exception e) {
            Log.e(TAG, Log.getStackTraceString(e));
        }
    }
    return false;
}

使用常量的地方

private static final String TAG = "KeyStoreHelper";
private static final String KEY_ALIAS = "MyApp_Key_Alias";
private static final String CIPHER_TYPE = "RSA/ECB/PKCS1Padding";
private static final String KEYSTORE_TYPE = "AndroidKeyStore";

这张支票对我来说很好。这可能会对您有所帮助。

注意:您可能已经有了一些更好的解决方案。如果是这样,请在此处发布。