Как поделиться секретным ключом (конфиденциальной информацией) между различными приложениями Android?
Я пытаюсь подключить устройство Bluetooth к нескольким приложениям для Android. Я хочу использовать один и тот же долгосрочный ключ (LTK) для всех приложений (AES256) и извлекать ключи сеанса из этого LTK в каждом приложении для создания безопасного коммуникационного туннеля. Я использую общие предпочтения в частном режиме, который позволяет приложениям с одинаковым идентификатором пакета получать доступ к одним и тем же данным, но, к сожалению, общие предпочтения недостаточно безопасны, и данные также доступны для других запросов уровня корневого доступа. Я использую хранилище ключей Android для хранения LTK (части реализации кода прилагаются), но мне нужно улучшить решение для двух сценариев:
1. Приложения с одинаковым идентификатором пакета.
а также
2. Приложения с разными идентификаторами пакетов, использующие один и тот же SDK.
Я ищу безопасный способ хранения LTK на устройстве Android, который доступен для этих конкретных приложений.
//-----
private boolean saveLTK(byte[] userKey)
{
try
{
prefEncryptCipher.init(Cipher.ENCRYPT_MODE, preferenceKey);
SharedPreferences settings = context.createPackageContext(packageNameSpace,
Context.MODE_PRIVATE).getSharedPreferences(KEY_PREFS_NAME, Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
byte[] encUsrKey = prefEncryptCipher.doFinal(userKey);
ByteBuffer byteBuffer = ByteBuffer.allocate(4 + prefEncryptCipher.getIV().length + encUsrKey.length);
byteBuffer.putInt(prefEncryptCipher.getIV().length);
byteBuffer.put(prefEncryptCipher.getIV());
byteBuffer.put(encUsrKey);
byte[] encUsrKeyMessage = byteBuffer.array();
editor.putString(encodeToString(address.getBytes(), DEFAULT), encodeToString(encUsrKeyMessage, DEFAULT));
return editor.commit();
}
catch (PackageManager.NameNotFoundException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException e)
{
e.printStackTrace();
}
return false;
}
//-----
private boolean loadLTK(byte[] userKey)
{
try
{
SharedPreferences settings = context.createPackageContext(packageNameSpace,
Context.MODE_PRIVATE).getSharedPreferences(KEY_PREFS_NAME, Activity.MODE_PRIVATE);
String userKeyStr = settings.getString(encodeToString(address.getBytes(), DEFAULT), null);
if (userKeyStr != null)
{
byte[] decUsrKey = decode(userKeyStr, DEFAULT);
ByteBuffer byteBuffer = ByteBuffer.wrap(decUsrKey);
int ivLength = byteBuffer.getInt();
byte[] iv = new byte[ivLength];
byteBuffer.get(iv);
byte[] decUsrKeyText = new byte[byteBuffer.remaining()];
byteBuffer.get(decUsrKeyText);
prefDecryptCipher.init(Cipher.DECRYPT_MODE, preferenceKey, new GCMParameterSpec(128, iv));
byte[] userKeyStrBytes = prefDecryptCipher.doFinal(decUsrKeyText);
if (userKeyStrBytes.length == userKey.length)
{
System.arraycopy(userKeyStrBytes, 0, userKey, 0, userKeyStrBytes.length);
return true;
}
}
}
catch (PackageManager.NameNotFoundException | BadPaddingException | IllegalBlockSizeException | InvalidAlgorithmParameterException | InvalidKeyException e)
{
e.printStackTrace();
}
return false;
}
Есть ли решение, похожее на брелок Apple, доступное для Android сейчас? (Я думаю, что цепочка ключей Android работает по-другому. Я предпочитаю такое решение, как цепочка ключей Apple, для передачи надежности безопасности и вызовов на уровень ОС.)
ИЛИ, я должен использовать общие настройки и защитить их сам? В связи с этим, если мне следует использовать Android Keystore для генерации и хранения этого LTK, позволяет ли хранилище ключей Android получать доступ к одному и тому же ключу из разных приложений с разными идентификаторами пакетов? Пожалуйста, опишите различные варианты и ограничения.