C #: Blowfish не работает с меньшим количеством букв - PullRequest
0 голосов
/ 01 апреля 2009

Я использую новейшую версию Blowfish.NET, но есть одна проблема.

responce = new byte[6]
{
     0x00, 0x80 ,0x01, 0x61, 0x00, 0x00
};
byte[] encrypted = new byte[responce.Length];
blowfish.Encrypt(responce, 2, encrypted, 2, input.Length - 2);

Я назвал это правильно, я хочу, чтобы он начал чтение / запись с третьего байта, и длина 6 - 2, потому что я не использую два байта.

Проблема:

        public int Encrypt(
        byte[] dataIn,
        int posIn,
        byte[] dataOut,
        int posOut,
        int count) 
    {
        uint[] sbox1 = this.sbox1;
        uint[] sbox2 = this.sbox2;
        uint[] sbox3 = this.sbox3;
        uint[] sbox4 = this.sbox4;

        uint[] pbox = this.pbox;

        uint pbox00 = pbox[ 0];
        uint pbox01 = pbox[ 1];
        uint pbox02 = pbox[ 2];
        uint pbox03 = pbox[ 3];
        uint pbox04 = pbox[ 4];
        uint pbox05 = pbox[ 5];
        uint pbox06 = pbox[ 6];
        uint pbox07 = pbox[ 7];
        uint pbox08 = pbox[ 8];
        uint pbox09 = pbox[ 9];
        uint pbox10 = pbox[10];
        uint pbox11 = pbox[11];
        uint pbox12 = pbox[12];
        uint pbox13 = pbox[13];
        uint pbox14 = pbox[14];
        uint pbox15 = pbox[15];
        uint pbox16 = pbox[16];
        uint pbox17 = pbox[17]; // till this line count is 4

        count &= ~(BLOCK_SIZE - 1); //count becomes 0 after that calc :((

        int end = posIn + count; // 2 + 0 = 2

        while (posIn < end) //no loop :[
        {
            uint hi = (((uint)dataIn[posIn + 3]) << 24) |
                      (((uint)dataIn[posIn + 2]) << 16) |
                      (((uint)dataIn[posIn + 1]) <<  8) |
                              dataIn[posIn    ];

            uint lo = (((uint)dataIn[posIn + 7]) << 24) |
                      (((uint)dataIn[posIn + 6]) << 16) |
                      (((uint)dataIn[posIn + 5]) <<  8) |
                              dataIn[posIn + 4];
            posIn += 8; 

            hi ^= pbox00;
            lo ^= (((sbox1[(int)(hi >> 24)] + sbox2[(int)((hi >> 16) & 0x0ff)]) ^ sbox3[(int)((hi >> 8) & 0x0ff)]) + sbox4[(int)(hi & 0x0ff)]) ^ pbox01;
            hi ^= (((sbox1[(int)(lo >> 24)] + sbox2[(int)((lo >> 16) & 0x0ff)]) ^ sbox3[(int)((lo >> 8) & 0x0ff)]) + sbox4[(int)(lo & 0x0ff)]) ^ pbox02;
            lo ^= (((sbox1[(int)(hi >> 24)] + sbox2[(int)((hi >> 16) & 0x0ff)]) ^ sbox3[(int)((hi >> 8) & 0x0ff)]) + sbox4[(int)(hi & 0x0ff)]) ^ pbox03;
            hi ^= (((sbox1[(int)(lo >> 24)] + sbox2[(int)((lo >> 16) & 0x0ff)]) ^ sbox3[(int)((lo >> 8) & 0x0ff)]) + sbox4[(int)(lo & 0x0ff)]) ^ pbox04;
            lo ^= (((sbox1[(int)(hi >> 24)] + sbox2[(int)((hi >> 16) & 0x0ff)]) ^ sbox3[(int)((hi >> 8) & 0x0ff)]) + sbox4[(int)(hi & 0x0ff)]) ^ pbox05;
            hi ^= (((sbox1[(int)(lo >> 24)] + sbox2[(int)((lo >> 16) & 0x0ff)]) ^ sbox3[(int)((lo >> 8) & 0x0ff)]) + sbox4[(int)(lo & 0x0ff)]) ^ pbox06;
            lo ^= (((sbox1[(int)(hi >> 24)] + sbox2[(int)((hi >> 16) & 0x0ff)]) ^ sbox3[(int)((hi >> 8) & 0x0ff)]) + sbox4[(int)(hi & 0x0ff)]) ^ pbox07;
            hi ^= (((sbox1[(int)(lo >> 24)] + sbox2[(int)((lo >> 16) & 0x0ff)]) ^ sbox3[(int)((lo >> 8) & 0x0ff)]) + sbox4[(int)(lo & 0x0ff)]) ^ pbox08;
            lo ^= (((sbox1[(int)(hi >> 24)] + sbox2[(int)((hi >> 16) & 0x0ff)]) ^ sbox3[(int)((hi >> 8) & 0x0ff)]) + sbox4[(int)(hi & 0x0ff)]) ^ pbox09;
            hi ^= (((sbox1[(int)(lo >> 24)] + sbox2[(int)((lo >> 16) & 0x0ff)]) ^ sbox3[(int)((lo >> 8) & 0x0ff)]) + sbox4[(int)(lo & 0x0ff)]) ^ pbox10;
            lo ^= (((sbox1[(int)(hi >> 24)] + sbox2[(int)((hi >> 16) & 0x0ff)]) ^ sbox3[(int)((hi >> 8) & 0x0ff)]) + sbox4[(int)(hi & 0x0ff)]) ^ pbox11;
            hi ^= (((sbox1[(int)(lo >> 24)] + sbox2[(int)((lo >> 16) & 0x0ff)]) ^ sbox3[(int)((lo >> 8) & 0x0ff)]) + sbox4[(int)(lo & 0x0ff)]) ^ pbox12;
            lo ^= (((sbox1[(int)(hi >> 24)] + sbox2[(int)((hi >> 16) & 0x0ff)]) ^ sbox3[(int)((hi >> 8) & 0x0ff)]) + sbox4[(int)(hi & 0x0ff)]) ^ pbox13;
            hi ^= (((sbox1[(int)(lo >> 24)] + sbox2[(int)((lo >> 16) & 0x0ff)]) ^ sbox3[(int)((lo >> 8) & 0x0ff)]) + sbox4[(int)(lo & 0x0ff)]) ^ pbox14;
            lo ^= (((sbox1[(int)(hi >> 24)] + sbox2[(int)((hi >> 16) & 0x0ff)]) ^ sbox3[(int)((hi >> 8) & 0x0ff)]) + sbox4[(int)(hi & 0x0ff)]) ^ pbox15;
            hi ^= (((sbox1[(int)(lo >> 24)] + sbox2[(int)((lo >> 16) & 0x0ff)]) ^ sbox3[(int)((lo >> 8) & 0x0ff)]) + sbox4[(int)(lo & 0x0ff)]) ^ pbox16;

            lo ^= pbox17;

            dataOut[posOut + 3] = (byte)(lo >> 24);
            dataOut[posOut + 2] = (byte)(lo >> 16);
            dataOut[posOut + 1] = (byte)(lo >>  8);
            dataOut[posOut    ] = (byte) lo;

            dataOut[posOut + 7] = (byte)(hi >> 24);
            dataOut[posOut + 6] = (byte)(hi >> 16);
            dataOut[posOut + 5] = (byte)(hi >>  8);
            dataOut[posOut + 4] = (byte) hi;

            posOut += 8;
        }

        return count;
    }

Blowfish отлично работает, если я передаю более длинные данные, но мне нужно зашифровать этот. Мы нашли проблему, но мой вопрос: как ее исправить?!

Ответы [ 3 ]

7 голосов
/ 01 апреля 2009

Я не очень знаком с алгоритмом Blowfish или, если на то пошло, библиотекой, которую вы используете. Но, в целом, я бы сказал, что если у вас есть проблемы с вашими данными, недостаточно длинными для шифрования, вы можете дополнить их. Другими словами ... Если ваши данные недостаточно длинные, добавьте группу нулей (или какой-либо другой символ, если нули придают вам особое значение) в начале или конце данных, прежде чем шифровать их. Затем, когда вы расшифруете его, обрежьте символы заполнения.

2 голосов
/ 01 апреля 2009

Существуют стандартные способы дополнить данные, чтобы они имели правильную длину для данного алгоритма блочного шифрования.

Эта страница содержит хороший обзор доступных параметров.

Нам нужно дополнить блок отступами. байтов, чтобы сделать это до требуемого длина. Есть как минимум пять общих условные обозначения:

  1. Pad с байтами, все с тем же значением, что и количество байтов заполнения.
  2. Пад с 0x80, за которым следуют ноль байтов
  3. Пад с нулями, за исключением того, что последний байт равен числу байты заполнения
  4. Pad с нулевыми (нулевыми) символами
  5. Pad с пробелами

Первый метод - это метод, описанный в PKCS # 5, PKCS # 7 и RFC 3852, раздел 6.3 (ранее RFC 3369 и RFC 2630). Это наиболее часто используемый, и тот, который мы рекомендуем в отсутствие каких-либо других соображений.

Но так как вы, кажется, всегда шифруете короткое сообщение фиксированной длины, заполнение может эффективно ослабить шифрование. Вы можете дополнить его случайными числами и выбросить после расшифровки.

2 голосов
/ 01 апреля 2009

Вы пытаетесь использовать блочный шифр для чего-то, что не является точно одним размером блока. Если ваши данные не будут иметь длину ровно 8 байтов, вы должны использовать существующий алгоритм заполнения и четко определенный режим. Тем не менее, почему вы реализуете свою собственную функцию blowfish вместо использования готовой библиотеки?

...