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_myUartKeyfile 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_myUartKeyfile 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));
}