首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >isInsideSecureHardware()为Android7.1.1返回false。如何强制将密钥存储在硬件中?

isInsideSecureHardware()为Android7.1.1返回false。如何强制将密钥存储在硬件中?
EN

Stack Overflow用户
提问于 2020-06-17 09:23:24
回答 1查看 409关注 0票数 1

我正在使用KeyStore将我的应用程序秘密安全地存储在安卓系统中。然而,我发现对于带有Android7.1.1及更低版本的设备,使用KeyStore存储的密钥不是“硬件支持的?”,也就是说,每当我将isInsideSecureHardware()方法调用到KeyInfo时,它总是会返回'false‘。

据我测试,即使设备在设置->Security->凭证存储->存储类型中具有“Storage type =Hardware”,也会发生这种情况。但是,Android7.1.2和更高版本的情况并非如此,只要凭据存储类型是硬件支持的,它总是为isInsideSecureHardware()返回“true”;从未尝试过其他类型。

  1. 是否存在强制将密钥存储在Android7.1.1的安全硬件中,将其降至4.3 (据我理解,这是在KeyStore中引入HSM的地方;如果我错了,请纠正我)?
  2. 如果存储的密钥不在安全硬件中,任何人都能说明会发生什么吗?密钥存储在哪里?有多安全?为了简单起见,isInsideSecureHardware == true与isInsideSecureHardware == false之间有什么区别?

下面是我的代码片段,用于注入密钥并检查KeyInfo (是的,我请求安卓4.3...please忽略代码中的版本检查):

代码语言:javascript
运行
复制
private void injectKey(Context context, String keyName){
    KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        end.add(Calendar.YEAR, 1);

        keyGenerator.init(new KeyGenParameterSpec.Builder(keyName, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                .setRandomizedEncryptionRequired(true)
                .setKeyValidityStart(start.getTime())
                .setKeyValidityEnd(end.getTime())
                //.setUserAuthenticationRequired(true) //need PIN to get key
                //.setUserAuthenticationValidityDurationSeconds(86400) //1-day time can use key from entering PIN
                //.setUnlockedDeviceRequired(true) API level 28
                //.setIsStrongBoxBacked(true) API level 28
                .build()
        );
    }

    SecretKey secretKey = keyGenerator.generateKey();

    //check key info
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        SecretKeyFactory factory = SecretKeyFactory.getInstance(secretKey.getAlgorithm(), "AndroidKeyStore");
        KeyInfo keyInfo;

        try {
            keyInfo = (KeyInfo) factory.getKeySpec(secretKey, KeyInfo.class);
            boolean insideHW = keyInfo.isInsideSecureHardware();
            boolean authReq = keyInfo.isUserAuthenticationRequired();
            boolean authHW = keyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware();
            String[] blockModes = keyInfo.getBlockModes();
            String[] digests = keyInfo.getDigests();
            String[] encryptionPaddings = keyInfo.getEncryptionPaddings();
            int keySize = keyInfo.getKeySize();
            Date keyValidityStart = keyInfo.getKeyValidityStart();
            Date keyEndValid = keyInfo.getKeyValidityForConsumptionEnd();
            String keyAlias = keyInfo.getKeystoreAlias();
            int keyPurpose = keyInfo.getPurposes();
            String [] signaturePaddings = keyInfo.getSignaturePaddings();
            int authType = keyInfo.getUserAuthenticationValidityDurationSeconds();

            MainActivity.showMessage(context, "Key Info",
                    "inside HW = " + insideHW + "\n" +
                            "auth Req = " + authReq + "\n" +
                            "auth HW = " + authHW + "\n" +
                            "keySize = " + keySize + "\n" +
                            "keyValidityStart = " + keyValidityStart + "\n" +
                            "keyEndValid = " + keyEndValid + "\n" +
                            "keyAlias = " + keyAlias + "\n" +
                            "keyPurpose = " + keyPurpose + "\n" +
                            "authType = " + authType + "\n");

            String checkKeyInfo = "";
        } catch (InvalidKeySpecException e) {
            String checkKeyInfo = "";
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2021-01-29 20:16:41

虽然Android硬件密钥库只支持从API 23开始存储AES密钥,但是版本与您的发现并不完全一致--您可能会更成功地使用RSA密钥,因为这些密钥是从API 18开始支持的。

链接到developer.android.com上的相关文档

这就是为什么因特网上存在“如何使用硬件密钥存储库加密”的例子,建议在密钥存储库中创建RSA密钥,使用SecureRandom或类似的方法创建256位AES密钥,然后使用私密的RSA密钥加密AES密钥,并将结果存储在SharedPreferences中。这可以在API 18+上工作,而不需要更改。

因此,尝试使用RSA密钥,您将有更多的运气,但仍然没有前API 18。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62425689

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档