Произвольный доступ к зашифрованным данным в режиме AES GCM

Существует очень хороший пример режима произвольного доступа AES CTR, и он работает: Произвольный доступ к InputStream с использованием режима AES CTR в Android

private static final int AES_BLOCK_SIZE = 16;
private static IvParameterSpec calculateIVForOffset(final IvParameterSpec iv,
    final long blockOffset) {
final BigInteger ivBI = new BigInteger(1, iv.getIV());
final BigInteger ivForOffsetBI = ivBI.add(BigInteger.valueOf(blockOffset
        / AES_BLOCK_SIZE));

final byte[] ivForOffsetBA = ivForOffsetBI.toByteArray();
final IvParameterSpec ivForOffset;
if (ivForOffsetBA.length >= AES_BLOCK_SIZE) {
    ivForOffset = new IvParameterSpec(ivForOffsetBA, ivForOffsetBA.length - AES_BLOCK_SIZE,
            AES_BLOCK_SIZE);
} else {
    final byte[] ivForOffsetBASized = new byte[AES_BLOCK_SIZE];
    System.arraycopy(ivForOffsetBA, 0, ivForOffsetBASized, AES_BLOCK_SIZE
            - ivForOffsetBA.length, ivForOffsetBA.length);
    ivForOffset = new IvParameterSpec(ivForOffsetBASized);
}

return ivForOffset;
}

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


person saganas    schedule 25.05.2017    source источник


Ответы (2)


Режим GCM использует режим счетчика для обеспечения конфиденциальности. Таким образом, можно расшифровать зашифрованный текст без аутентификации; взгляните на мой ответ здесь. Чтобы зашифровать или расшифровать по заданному смещению, вы можете изменить счетчик, чтобы изменить байты для данного смещения и XOR полученного зашифрованного текста. Однако вы не сможете проверить какой-либо зашифрованный текст, если пропустите хотя бы один байт.

Поэтому с GCM лучше разделить открытый текст на куски и зашифровать их отдельно.

person Maarten Bodewes    schedule 25.05.2017

AES GCM использует режим под названием GCTR. Он похож на CTR, но определяется очень особым образом.

Если IV не равен 12 байтам, он сначала хэшируется, чтобы получить 12-байтовый IV (функция GHASH определяется как однократное умножение на поле Галуа, то же, что и для MAC).

Затем 12-байтовый IV объединяется с 4-байтовым счетчиком (начиная с 1), чтобы получить 16-байтовый блок CTR.

Таким образом, обработка IV как BigInteger и увеличение его, как в вашем примере, определенно не сработает.

person rustyx    schedule 29.10.2018