将私钥存储在Android Keystore中

时间:2018-09-19 13:17:22

标签: java android encryption keystore

我正在开发一个将密钥存储在Android密钥库中的应用,但我希望此密钥能够防出厂重置。我已经看到密钥库Blob存储在/data/misc/keystore/user_0/10043_USRSKEY_myUartKey中,所以我计划手动将其备份到专用闪存中,并在恢复出厂设置后恢复它。

这确实很好,即使从出厂设置恢复后,我也可以通过从专用闪存中恢复密钥存储数据来恢复加密数据。

但是在测试中,我发现:

  • 将此10043_USRSKEY_myUartKey文件恢复到另一台设备也允许该另一台设备解密加密的数据。我的理解是,不可能从硬件支持的密钥库中提取密钥材料。我的TEE驱动程序或测试应用程序中的密钥库处理是否可能有问题?

  • 更改PIN码后,
  • 将此10043_USRSKEY_myUartKey文件恢复到同一设备上不会引起任何解密问题。再说一次,我的理解是密码是加密的一部分,所以我不知道如何解码 数据用另一个PIN加密。

  • 我还能够使用该文件从具有不同签名的另一个apk解密。因此,密钥访问显然没有绑定到apk签名吗?

这是我使用的示例代码:

private void InitialiseKeystore() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, PackageManager.NameNotFoundException, IOException, KeyStoreException, CertificateException {
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null);
    ArrayList<String> aliases = Collections.list(keyStore.aliases());
    for(String s : aliases){
        Log.d("ALIAS", s);
        ((TextView)findViewById(R.id.textView)).append(String.format("Found key: %s\n", s));
        if(myAlias.equals(s)) return;
    }
    ((TextView)findViewById(R.id.textView)).append("\nKey not found");
    //keyStore.deleteEntry("myUartKey");
    final KeyGenerator keyGenerator = KeyGenerator
            .getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
    ((TextView)findViewById(R.id.textView)).append("\nGENERATING KEY");
    final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(myAlias,
            KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
            .build();

    keyGenerator.init(keyGenParameterSpec);
    final SecretKey secretKey = keyGenerator.generateKey();
    ((TextView)findViewById(R.id.textView)).append("\nKEY GENERATED");
    final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    byte iv[] = cipher.getIV();
    Log.w("IV", Arrays.toString(iv));
    final byte textToEncrypt[] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,(byte)0x88, (byte)0x99,(byte)0xaa,(byte)0xbb,(byte)0xcc,(byte)0xdd,(byte)0xee,(byte)0xff};
    byte encryption[] = cipher.doFinal(textToEncrypt);
    //Get data directory
    PackageManager m = getPackageManager();
    String s = getPackageName();
    PackageInfo p = m.getPackageInfo(s, 0);
    s = p.applicationInfo.dataDir;
    File file = new File(s + File.separator + "myEncryptedUartKey.bin");
    file.createNewFile();
    //write the bytes in file
    if(file.exists())
    {
        OutputStream fo = new FileOutputStream(file);
        fo.write(iv);
        fo.write(encryption);
        fo.close();
        System.out.println("file created: "+file);
    }

    Log.i("ENC", Arrays.toString(encryption));
}

0 个答案:

没有答案