Как сохранить ключ после закрытия activity при шифровании
Encryption encryption = Encryption.getDefault("Key", "Salt", new byte[16]);
encrypted = encryption.encryptOrNull(encrypted);
decrypted = encryption.decryptOrNull(encrypted);
Так не получается
сохранение
SharedPreferences settings = getSharedPreferences("AppSettings", MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString("key", String.valueOf(encryption));
editor.apply();
загрузка
SharedPreferences settings = getSharedPreferences("AppSettings", MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
String encryption = (settings.getString("key", ""));
editor.apply();
decrypted=encryption;
Ответы (1 шт):
- Ключ нельзя сохранять (точка)
- Если очень хочется сохранить ключ (см. п.1)
- Если все равно хочется сохранить ключ еще раз посмотрите на п.1
Теперь более серьезно. Используются в общем случае 3 подхода как сохранять ключи (в случае Android)
1)Универсальный подход: ключ генерируется на основе пароля заданного юзером. Берем пароль и на его основе генерируем ключ. Процедура описана в т.н. PBKDF2 (Password Based Key Generation Function v.2). В коде выглядит примерно так:
public static String generateKey(String password, String salt) {
char[] chars = password.toCharArray();
byte[] salt = salt.getBytes();
PBEKeySpec spec = new PBEKeySpec(chars, salt, 1010101,
20 * Byte.SIZE);
SecretKeyFactory skf = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = skf.generateSecret(spec).getEncoded();
return toHex(salt) + ":" + toHex(hash);
}
То есть ничего не храним. Юзер задает пароль из пароля генерируем ключ и шифруем/дешифруем. Если ключ не подошел - ну извините.
2)В качестве пароля используем уникальный идентификатор устройства ANDROID_ID - обратите внимание:
64-bit number (expressed as a hexadecimal string), unique to each combination of app-signing key, user, and device. Values of ANDROID_ID are scoped by signing key and user.
то есть идентификатор генерируется для конкретного устройства и конкретного приложения + юзера устройства. То есть на другом приложении он будет другой. При хард ресете устройства он генерируется заново (что иногда может стать проблемой).
3)Используем Android Keystore - по сути криптографически защищенное устройство для хранения данных. Проблема в том, что некоторые Android девайсы предоставляют заведомо ущербные софтверные реализации. Настоящая реализация должна поддерживать т.н. TEE (Trusted Execution Environment) - защищенная среда исполнения (как правило, в виде специального чипа/процессора, внутри которого проводятся крипто-операции) - например Samsung KNOX или Titan M в Google Pixel. Проверить наличие хардверной реализации можно примерно так:
PrivateKey key = ...; // Android KeyStore key
KeyFactory factory = KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
KeyInfo keyInfo = factory.getKeySpec(key, KeyInfo.class);
boolean isHardwareBacked = keyInfo.isInsideSecureHardware();