ArgumentOutOfRangeException при вызове CfbBlockCipher.Init в BouncyCastle - PullRequest
0 голосов
/ 25 апреля 2011

Когда я выполняю следующий код:

        const int blockSize = 64;
        const int keySize = 256;

        string inputText;
        byte[] inputBytes;
        using (StreamReader reader = new StreamReader(inputFile))
        {
            inputText = reader.ReadToEnd();
            inputBytes = StringToBytes(inputText);
        }
        byte[] outputBytes = new byte[inputBytes.Length];

        CipherKeyGenerator keygen = new CipherKeyGenerator();
        SecureRandom rand = new SecureRandom();

        KeyGenerationParameters keygenParams = new KeyGenerationParameters(rand, keySize);
        keygen.Init(keygenParams);
        byte[] key = keygen.GenerateKey();

        BufferedBlockCipher cipher = null;
        ICipherParameters cipherParams = null;

                byte[] iv = new byte[blockSize];
                rand.NextBytes(iv);
                cipherParams = new ParametersWithIV(
                    new ParametersWithSBox(
                        new KeyParameter(key),
                        Gost28147Engine.GetSBox("E-A")),
                    iv);
                cipher = new BufferedBlockCipher(
                    new CfbBlockCipher(new Gost28147Engine(), subblockLength));

        cipher.Init(true, cipherParams);
        int bytesLength = cipher.ProcessBytes(inputBytes, 0, inputBytes.Length, outputBytes, 0);
        cipher.DoFinal(outputBytes, bytesLength);

... Я получаю следующее исключение:

System.ArgumentOutOfRangeException was unhandled
  Source=mscorlib
  ParamName=dstIndex
  StackTrace:
       w System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
       w System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length)
       w Org.BouncyCastle.Crypto.Modes.CfbBlockCipher.Init(Boolean forEncryption, ICipherParameters parameters)
       w Org.BouncyCastle.Crypto.BufferedBlockCipher.Init(Boolean forEncryption, ICipherParameters parameters)
       ...

1 Ответ

0 голосов
/ 25 апреля 2011

Уже решена проблема.В new CfbBlockCipher(new Gost28147Engine(), subblockLength)) размер блока должен быть передан как количество битов, а не байтов.Размер IV должен совпадать с размером блока, передаваемого конструктору CfbBlockCipher, поэтому код выглядит следующим образом: byte[] iv = new byte[subblockLength]

Просмотр CfbBlockCipher.Init, исключение легко отследить отсюда:

/**
* Initialise the cipher and, possibly, the initialisation vector (IV).
* If an IV isn't passed as part of the parameter, the IV will be all zeros.
* An IV which is too short is handled in FIPS compliant fashion.
*
* @param forEncryption if true the cipher is initialised for
*  encryption, if false for decryption.
* @param param the key and other data required by the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public void Init(
    bool forEncryption,
    ICipherParameters parameters)
{
    this.encrypting = forEncryption;
    if (parameters is ParametersWithIV)
    {
        ParametersWithIV ivParam = (ParametersWithIV) parameters;
        byte[] iv = ivParam.GetIV();
        int diff = IV.Length - iv.Length;
        Array.Copy(iv, 0, IV, diff, iv.Length);
        Array.Clear(IV, 0, diff);

        parameters = ivParam.Parameters;
    }
    Reset();
    cipher.Init(true, parameters);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...