Неверный размер буфера, возвращаемый поставщиком по умолчанию - PullRequest
0 голосов
/ 18 февраля 2019

С Android 9 и API 28 провайдер Bouncy Castle («BC») больше не поддерживается, и попытка его использования приводит к NoSuchAlgorithmException.Согласно официальному сообщению в блоге от Android, способ исправить это состоит в том, чтобы вообще не указывать поставщика.

Однако кажется, что поставщик по умолчанию ведет себя иначе, чем поставщик Bouncy Castle -в DECRYPT_MODE метод getOuptputSize возвращает другое значение для того же параметра.Приведенный ниже код показывает, что поставщик BC возвращает 35, а поставщик по умолчанию возвращает 51, когда запрашивает размер вывода зашифрованного буфера 51:

Cipher aesGCMCipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(AES_KEY_SIZE_IN_BITS, new byte[12]);
aesGCMCipher.init(Cipher.DECRYPT_MODE, aesSecretKey, gcmParameterSpec);
LOG.i("(Decrypt) BC provider output size: " + aesGCMCipher.getOutputSize(51));

Cipher defaultAesGCMCipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec defaultGcmParameterSpec = new GCMParameterSpec(AES_KEY_SIZE_IN_BITS, new byte[12]);
defaultAesGCMCipher.init(Cipher.DECRYPT_MODE, aesSecretKey, defaultGcmParameterSpec);
LOG.i("(Decrypt) Default provider output size: " + defaultAesGCMCipher.getOutputSize(51));

// Ouptput:
(Decrypt) BC provider output size: 35
(Decrypt) Default provider output size: 51

Обратите внимание, что значения, возвращаемые в ENCRYPT_MODE, являютсято же самое:

Cipher aesGCMCipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(AES_KEY_SIZE_IN_BITS, new byte[12]);
aesGCMCipher.init(Cipher.ENCRYPT_MODE, aesSecretKey, gcmParameterSpec);
LOG.i("(Encrypt) BC provider output size: " + aesGCMCipher.getOutputSize(35));

Cipher defaultAesGCMCipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec defaultGcmParameterSpec = new GCMParameterSpec(AES_KEY_SIZE_IN_BITS, new byte[12]);
defaultAesGCMCipher.init(Cipher.ENCRYPT_MODE, aesSecretKey, defaultGcmParameterSpec);
LOG.i("(Encrypt) Default provider output size: " + defaultAesGCMCipher.getOutputSize(35));

// Output
(Encrypt) BC provider output size: 51
(Encrypt) Default provider output size: 51

Является ли код для определения размера выходного буфера неправильным и нуждается в перезаписи, или это ошибка в реализации, которая требует обходного пути?Прямо сейчас, поскольку возвращаемое значение неверно, выделенный буфер слишком велик, что приводит к повреждению сообщений (дополнительные байты добавляются к сообщению).Мне кажется, это ошибка, но я не решаюсь произвольно сократить последние 16 байтов, потому что, если ошибка будет исправлена, код снова будет регрессировать.

...