Как рассчитать AES GCM IV для конкретного блока - PullRequest
0 голосов
/ 28 декабря 2018

Я сейчас использую CES CTR для шифрования наших документов.Это сделано для того, чтобы предоставить возможность делать запросы диапазона к зашифрованным документам.С AES CTR можно рассчитать IV для конкретного блока с помощью простой функции, подобной этой:

    private static int AES_BLOCK_SIZE = 16;

    private static ParametersWithIV CalculateIvForOffset(KeyParameter sk, ParametersWithIV iv,  long blockOffset) 
    {
        var ivBI = new BigInteger(1, iv.GetIV());
        var ivForOffsetBi = ivBI.Add(BigInteger.ValueOf(blockOffset/ AES_BLOCK_SIZE));

        var ivForOffsetBA = ivForOffsetBi.ToByteArray();
        ParametersWithIV ivForOffset;
        if (ivForOffsetBA.Length >= AES_BLOCK_SIZE) {
            ivForOffset = new ParametersWithIV(sk, ivForOffsetBA, ivForOffsetBA.Length - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
        } else {
            byte[] ivForOffsetBASized = new byte[AES_BLOCK_SIZE];
            Array.Copy(ivForOffsetBA, 0, ivForOffsetBASized, AES_BLOCK_SIZE
                    - ivForOffsetBA.Length, ivForOffsetBA.Length);
            ivForOffset = new ParametersWithIV(sk, ivForOffsetBASized);/**/
        }

        return ivForOffset;

}

Я использую BouncyCastle в своем приложении.Но в отдельных случаях мне нужно отслеживать целостность документа.И я хочу использовать AES GCM для этой цели.Однако мне все еще нужна способность расшифровывать определенный блок данных.Можно ли рассчитать IV для конкретной позиции / блока GCM и как это сделать?

Упрощенный код, который я использую для расшифровки шифрования, находится здесь:

        var offset = 0;
        var decryptionSize = 128;
        var file = Hex.Decode("2B7E151628AED2A6ABF7158809CF4F3C12312312312312312312312312312312312391792837012937019238102938012938017230192830192830192830192730129730129830192380192730192730");

        var encryptor = CipherUtilities.GetCipher("AES/GCM/NoPadding");

        var sk = ParameterUtilities.CreateKeyParameter("AES", Hex.Decode("2B7E151628AED2A6ABF7158809CF4F3C"));
        encryptor.Init(true, new ParametersWithIV(sk, Hex.Decode("F0F1F2F3F4F5F6F7F8F9FAFBFCFD0001")));
        var encryptedFile = encryptor.DoFinal(file);

        var decryptor = CipherUtilities.GetCipher("AES/GCM/NoPadding");
        var arrayToDecrypt = encryptedFile.Skip(offset).Take(decryptionSize).ToArray();

        // recalculate initial vector for offset
        var newiv = CalculateIvForOffset(sk, new ParametersWithIV(sk, Hex.Decode("F0F1F2F3F4F5F6F7F8F9FAFBFCFD0001")),offset);
        decryptor.Init(false, newiv);
        var output2 = decryptor.ProcessBytes(arrayToDecrypt, 0, arrayToDecrypt.Length);

Спасибо!

Ответы [ 2 ]

0 голосов
/ 01 января 2019

Спасибо за помощь!Да, нашел все ответы из официальной документации .Реализовал мой вариант генерации IV для конкретного блока, используя пример, приведенный в этом посте

0 голосов
/ 30 декабря 2018

GCM основан на комбинации шифрования в режиме CTR и кода аутентификации сообщения GHASH .Поэтому, если вы не хотите проверять целостность сообщения (или уже сделали это, и можете быть уверены, что сообщение не было подделано с тех пор), вы можете просто проигнорировать тег аутентификации GHASH и расшифровать сообщение так же, какесли он был зашифрован с использованием обычного режима CTR.

Одна деталь, о которой следует знать, - это то, что GCM использует значение счетчика 0 для генерации тега аутентификации, тогда как последовательность счетчиков для фактического потока ключей шифрования начинается с 1. Таким образом, выдолжен иметь возможность использовать тот же код для расчета значений счетчика, что и для основного режима CTR, но вам нужно будет сместить результаты на единицу.

...