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.

4
  • workingHash is rage.Length - 16, so you cant copy rage.Length bytes. this looks like it is missing a windows phone tag Commented Jan 31, 2016 at 13:58
  • 1
    Did you debug your own code? Seems a issue trivial for someone dealing with AES encryption. Commented Jan 31, 2016 at 13:58
  • Of courseI debugged it... Anyways... fixed. Commented Jan 31, 2016 at 13:59
  • It is also possible (and more common) to store the IV to the raw stream by itself so you can use stream.Write/Read with it and not have to go thru all that and whatever you are doing to prepend the IV to it when encrypting. see stackoverflow.com/q/8041451/1070452 Commented Jan 31, 2016 at 14:13

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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

1 Comment

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!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.