0

I want to generate an Initialization Vector (IV) for my AES encryption method. I have defined the key size as 256 (since I am using AES) so my IV needs to 32 bytes in length (256 / 8). I wish to store the IV as a string representation so using UTF-8, this would equate to a 16 character string.

Here is the code I am using to generate and return the IV ...

using (var aesProv = new AesCryptoServiceProvider())
{
  aesProv.GenerateIV();
  return System.Text.Encoding.Default.GetString(aesProv.IV);
}

How do I go about making sure that the IV is 16 characters in length? Can I count on a 16 character length being generated because I am using an AES library? AesCryptoServiceProvider

webworm
  • 10,587
  • 33
  • 120
  • 217
  • 1
    16 characters and UTF-8 do not seem to be a good match if you aim to store 32-bytes (since each UTF-8 character can be represented in 1 byte). You may need to make 2 of them... – Ian Mar 17 '16 at 15:38
  • @Ian: Did you mean *not* all UTF-8 characters can be represented in one byte? – Jon Skeet Mar 17 '16 at 15:43
  • @JonSkeet my bad... you are right, *not* all... – Ian Mar 17 '16 at 15:46
  • *"I have defined the key size as 256 (since I am using AES) so my IV needs to 32 bytes in length"* - **No.** AES has a fixed block size of 128 bit, which is also the IV size. AES supports different key sizes, which are independent of the block size. – Artjom B. Mar 17 '16 at 20:16
  • *"32 bytes (16 characters)"* - Usually, this is the other way around where 32 hex-encoded characters can represent 16 arbitrary bytes. – Artjom B. Mar 17 '16 at 20:17
  • @Artjom- Perhaps my information is incorrect then. If I want to make use of AES 256 bit encryption does it matter what length the Initialization Vector is? – webworm Mar 17 '16 at 20:19
  • @webworm Yes, it matters what size the IV has. For CBC mode it must be the same as the block size: 16 bytes. No more, no less. For other modes it can be different. ECB: 0B, CFB: 16B, CTR: Variable (12B recommended). – Artjom B. Mar 17 '16 at 20:21

1 Answers1

3

I wish to store the IV as a string representation so using UTF-8, this would equate to a 16 character string.

No. Just don't do this. Yes, you could interpret the 32 bytes as a UCS-2 sequence, but it's a really bad idea. This isn't naturally text - it's arbitrary binary data, basically. You could very easily end up with an invalid sequence of UTF-16 code units, due to surrogate pairs etc.

Assuming you want a string representation that you're likely to be able to transport safely etc, I'd suggest just using base64:

return Convert.ToBase64String(aesProv.IV);

Or you could use hex, of course. Both of these will be considerably longer than 16 characters of course, but that's the "price" of dealing with data appropriately.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks for the advice! It doesn't matter to me what length the string ends up being as long as it converts back to 32 bytes for use in the encryption/decryption process. – webworm Mar 17 '16 at 15:51
  • @webworm: Right - using hex or base64 is good for that. With base64 you need to be slightly careful if you're going to use it in URLs or anything like that, but it's otherwise pretty nice. – Jon Skeet Mar 17 '16 at 15:52