tags:

views:

361

answers:

3

Hello,

I'm using Blowfish.NET newest version,but there is one problem.

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);

I called it the right way,I want it to start read/write from the third byte and the length is 6 - 2,because i dont use two bytes.

The problem:

        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;
    }

The blowfish works fine if i pass longer data,but I need to encrypt this one.We've found the problem,but my question is:How to fix it?!

+7  A: 

I'm not super familiar with the Blowfish algorithm or, for that matter, the library you're using. But, in general, I'd say that if you're having issues with your data not being long enough to encrypt, you could pad it. In other words... If you data isn't long enough, add a bunch of zeros (or some other character if zeros hold special meaning to you) to the beginning or end of the data before you encrypt it. Then, when you decrypt it, trim the padding characters.

dustyburwell
+2  A: 

You're trying to use a block cipher on something which is not exactly one block in size. If your data is not going to be exactly 8 bytes long, you should be using an existing padding algorithm along with a well-defined mode. That said, why are you implementing your own blowfish function instead of using a pre-made library?

Yuliy
+1  A: 

There are standard ways to pad data so that it has the right length for a given block encryption algorithm.

This page contains a good overview of the available options.

We need to pad the block with padding bytes to make it up to the required length. There are at least five common conventions:

  1. Pad with bytes all of the same value as the number of padding bytes
  2. Pad with 0x80 followed by zero bytes
  3. Pad with zeroes except make the last byte equal to the number of padding bytes
  4. Pad with zero (null) characters
  5. Pad with space characters

Method one is the method described in PKCS#5, PKCS#7 and RFC 3852 Section 6.3 (formerly RFC 3369 and RFC 2630). It is the most commonly used, and the one we recommend in the absence of any other considerations.

But since you seem to be always encrypting a short fixed-length message, padding could effectively weaken the encryption. You could pad it with random numbers and throw them away after decryption.

TomA