0

So I need to cut off the first 16 bytes from my byte array. I followed another post I saw on Stack Overflow to use the following code:

//split message into iv and encrypted bytes
byte[] iv = new byte[16];
byte[] workingHash = new byte[rage.Length - 16];

//put first 16 bytes into iv
for (int i = 0; i < 16; i++)
{
    iv[i] = rage[i];
}

Buffer.BlockCopy(rage, 16, workingHash, 0, rage.Length);

What we are trying here is to cut off the first 16 bytes from the byte[] rage and put the rest into byte[] workingHash

The error occurs at Buffer.BlockCopy(rage, 16, workingHash, 0, rage.Length);

Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.

Any help will be much appreciated.

Ondrej Tucny
  • 27,626
  • 6
  • 70
  • 90
Raghav J.
  • 53
  • 8

3 Answers3

1

The problem is trivial: Buffer.BlockCopy's last argument requires the correct number of bytes to be copied, which (taking the starting index into account) may not exceed the array's bounds (docs).

Hence the code should look like this, avoiding any for cycles:

Buffer.BlockCopy(rage, 0, iv, 0, 16);
Buffer.BlockCopy(rage, 16, workingHash, 0, rage.Length - 16);

Notice the “- 16” at the second line, fixing the original code. The first line replaces the for cycle for the sake of consistency.

Ondrej Tucny
  • 27,626
  • 6
  • 70
  • 90
1

Lets assume rage is a byte array of length 20:

var rage = new byte[20]
{
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
};

After byte[] iv = new byte[16];, iv will contain:

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

After byte[] workingHash = new byte[rage.Length - 16];, workingHash will contain:

{ 0, 0, 0, 0 }

After the for loop iv is:

{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }

You need:

Buffer.BlockCopy(rage, 16, workingHash, 0, rage.Length - 16);

Copy rage.Length - 16 (4) elements from rage's 16th element (which is 17) to workingHash starting from the 0th element.

The result:

{ 17, 18, 19, 20 }

By the way there is a very readable way, probably not as fast as copying arrays, but worth mentioning:

var firstSixteenElements = rage.Take(16).ToArray();
var remainingElements = rage.Skip(16).ToArray();
Szabolcs Dézsi
  • 8,743
  • 21
  • 29
-1

Fixed:

                //split message into iv and encrypted bytes
                byte[] iv = new byte[16];
                byte[] workingHash = new byte[rage.Length - 16];

                //put first 16 bytes into iv
                for (int i = 0; i < 16; i++)
                {
                    iv[i] = rage[i];
                }

                for (int i = 0; i < rage.Length - 16; i++)
                {
                    workingHash[i] = rage[i + 16];
                }
Raghav J.
  • 53
  • 8
  • 2
    Bad fix. Better would be to understand the bug and keep the BlockCopy call which is much better code. The fix was just a `-16` somewhere. Don't rewrite hoping the bug goes away! – usr Jan 31 '16 at 14:03