Basic Android Encryption Do’s and Don’ts - статья с набором быстрых советов о том, что надо и что не надо делать при использовании шифрования в Android. Краткая выжимка:
Не используй AES в режиме ECB. По умолчанию Android (и Java) использует режим ECB при шифровании по алгоритму AES. Проблема режима ECB в том, что он может раскрыть подробности зашифрованной информации. Вместо него следует использовать режимы CBC и GCM:
// Как надо делать
Cipher.getInstance("AES/GCM/NOPADDING");
// Как не надо делать
Cipher.getInstance("AES");
Всегда используй случайный IV:
// Как надо делать
SecureRandom secureRandom = new SecureRandom();
byte[] iv = new byte[IV_LENGTH];
secureRandom.nextBytes(iv);
myCipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
// Как не надо делать
myCipher.init(Cipher.ENCRYPT_MODE, key);
byte[] iv = myCipher.getIV();
Заполняй важные массивы нулями после использования. Ты можешь забыть очистить массив, содержащий ключ и взломщик воспользуется этим чтобы извлечь ключ напрямую из оперативной памяти:
byte[] decrypt(byte[] dataToDecrypt, byte[] secretKey) {
// Расшифровываем данные
...
// Очищаем ключ
Arrays.fill(secretKey, (byte) 0);
return decryptedData;
}
Не используй AES в режиме ECB. По умолчанию Android (и Java) использует режим ECB при шифровании по алгоритму AES. Проблема режима ECB в том, что он может раскрыть подробности зашифрованной информации. Вместо него следует использовать режимы CBC и GCM:
// Как надо делать
Cipher.getInstance("AES/GCM/NOPADDING");
// Как не надо делать
Cipher.getInstance("AES");
Всегда используй случайный IV:
// Как надо делать
SecureRandom secureRandom = new SecureRandom();
byte[] iv = new byte[IV_LENGTH];
secureRandom.nextBytes(iv);
myCipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
// Как не надо делать
myCipher.init(Cipher.ENCRYPT_MODE, key);
byte[] iv = myCipher.getIV();
Заполняй важные массивы нулями после использования. Ты можешь забыть очистить массив, содержащий ключ и взломщик воспользуется этим чтобы извлечь ключ напрямую из оперативной памяти:
byte[] decrypt(byte[] dataToDecrypt, byte[] secretKey) {
// Расшифровываем данные
...
// Очищаем ключ
Arrays.fill(secretKey, (byte) 0);
return decryptedData;
}