Store private key in Android Keystore

Viewed 956

I am developping an app that stores key in Android keystore, but I want this key to be factory-reset-proof. I have seen that keystore blobs are stored in /data/misc/keystore/user_0/10043_USRSKEY_myUartKey so I plan to manually backup this blob in a dedicated flash and to restore it after a factory reset.

This did work fine, I was able to recover encrypted data, even after factory reset, by restoring the keystore data from dedicated flash.

But during my tests I have observed that:

  • restoring this 10043_USRSKEY_myUartKey file to another device also allow this other device to decrypt ciphered data. My understanding was that it was no possible to extract key materials from a hardware backed keystore. May I have an issue in my TEE driver or in the keystore handling in my test app ?

  • restoring this 10043_USRSKEY_myUartKey file to the same device after changing PIN code did not cause any decryption issue. Again, my understanding was that pincode was part of the encryption so I don't understand how I can still decode data ciphered with another PIN.

  • I was also able to use this file to decrypt from another apk with different signature. So the key access is apparently not binded to the apk signature, should it ?

here is sample code that I use:

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 Answers
Related