我正在开发一个将密钥存储在Android密钥库中的应用,但我希望此密钥能够防出厂重置。我已经看到密钥库Blob存储在/data/misc/keystore/user_0/10043_USRSKEY_myUartKey
中,所以我计划手动将其备份到专用闪存中,并在恢复出厂设置后恢复它。
这确实很好,即使从出厂设置恢复后,我也可以通过从专用闪存中恢复密钥存储数据来恢复加密数据。
但是在测试中,我发现:
将此10043_USRSKEY_myUartKey
文件恢复到另一台设备也允许该另一台设备解密加密的数据。我的理解是,不可能从硬件支持的密钥库中提取密钥材料。我的TEE驱动程序或测试应用程序中的密钥库处理是否可能有问题?
将此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));
}