首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用AndroidKeysetManager从Tink导出密钥集条目

用AndroidKeysetManager从Tink导出密钥集条目
EN

Stack Overflow用户
提问于 2020-10-23 15:00:38
回答 1查看 597关注 0票数 2

我在一个机器人项目中使用'androidx.security:security-crypto:1.1.0-alpha02‘。它适用于文件加密/解密。我已经在硬件密钥库中设置了一个主密钥,它需要使用身份验证。

代码语言:javascript
复制
private static MasterKey getOrCreateMasterKey(final Application application)
    throws IOException, GeneralSecurityException {
    return new MasterKey.Builder(application)
        .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
        .setUserAuthenticationRequired(true, 3600)
        .setRequestStrongBoxBacked(true)
        .build();
}

Security 自动生成了一个Tink密钥集文件,该文件适合于安卓共享首选项。

代码语言:javascript
复制
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="__androidx_security_crypto_encrypted_file_keyset__">129c0157ebfb4adffbd04e3ad4cd44336c5e89c3fe455d949031436c63789092960d8b93053de8e1fd855b61047a1d496ff26006958982e6a90f950746dbc7afc6b252bf51149b8404e5ff8616f9911ad54e153bf2c2c21eb571ca11223c77edd01b488465f7ab286ffd9054d7e396d1b2a187152dd9bf76ee5df9a5faefd5e5b7ec159fa04a860f9d237f833763f6c42acbcdedfb06a575264f948049b3841a4f08c094920612480a3d747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d486b646653747265616d696e674b6579100118c09492062003</string>
</map>

如果我理解正确的话,那就是用于加密文件的实际DEK。

现在的问题是,如果我想导出加密的文件,我将无法在另一个设备上解密,因为硬件KeyStore中的主密钥是不可导出的。

最好的解决方案是在密钥集中导出DEK,并使用PBKDF2将其解密到另一个设备密钥集中。

一个可选的解决方案是在密钥存储库之外创建主密钥材料,使用另一个keystore密钥保护它,并在需要时使用PBKDF2导出它。这将破坏库的逻辑流。

我尝试导入'com.google.crypto.tink:tink-android:1.5.0' Tink库,以便开始直接管理密钥集,因为Security没有实现这个usecase。

代码语言:javascript
复制
AndroidKeysetManager manager = new AndroidKeysetManager.Builder()
    .withSharedPref(getApplicationContext(), "my_keyset_name", "my_pref_file_name")
    .withKeyTemplate(AesGcmKeyManager.aes256GcmTemplate())
    .withMasterKeyUri(masterKeyUri)
    .build();

无论如何,我无法用这个管理器解密密钥集中的密钥,以便能够用密码加密并正确导出密钥。

你知道该如何面对这个问题吗?

EN

回答 1

Stack Overflow用户

发布于 2020-10-30 15:24:27

我在官方的"Tink TO“:https://github.com/google/tink/blob/master/docs/JAVA-HOWTO.md上找到了解决方案

只是有点不合常理。

因此,这里有一个可能的函数,用于导出以前用AndroidKeyStore在harware安全元素中生成的masterkey加密的特定密钥集:

代码语言:javascript
复制
 public byte[] exportKeyset(final String keysetName, final String password) throws
        IOException, GeneralSecurityException {


    AndroidKeysetManager backupKeySetManager = new AndroidKeysetManager.Builder()
            .withSharedPref(application, keysetName, "my_pref_file_name")
            .withKeyTemplate(AesGcmHkdfStreamingKeyManager.aes256GcmHkdf4KBTemplate())
            .withMasterKeyUri(MASTER_KEY_URI)
            .build();

    try(final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()){

        final byte[] saltBytes = new byte[16];
        new SecureRandom().nextBytes(saltBytes);

        final byte[] encryptionKeyMaterial =
                SecretKeyFactory.getInstance("PBKDF2withHmacSHA512")
                        .generateSecret(new PBEKeySpec(password.toCharArray(), saltBytes, 3000000, 256)).getEncoded();

        final AesGcmJce aesGcmJce = new AesGcmJce(encryptionKeyMaterial);

        CleartextKeysetHandle.write(backupKeySetManager.getKeysetHandle(),
                BinaryKeysetWriter.withOutputStream(byteArrayOutputStream));

        final byte[] clearKeyset = byteArrayOutputStream.toByteArray();

        byteArrayOutputStream.reset();
        byteArrayOutputStream.write(aesGcmJce.encrypt(clearKeyset, saltBytes));
        byteArrayOutputStream.write(saltBytes);

        return byteArrayOutputStream.toByteArray();

    }catch (IOException e){
        throw e;
    }

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

https://stackoverflow.com/questions/64502478

复制
相关文章

相似问题

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