IV generation with RNGCryptoServiceProvider



  • I'm using RNGCryptoServiceProvider.GetBytes(new byte[16]) to generate IV's to use in AES (256 bits) encryption. For every record I encrypt, I generate a new IV.

    I'm also prepending each of these IV's to the encrypted text (to avoid storing them on a different column in the DB), as I guess is the standard.

    However, to do that concatenation, I am using Convert.ToBase64String() to convert the IV byte array to a string first.

    After a few tests I found a couple patterns that concern me:

    • every IV, as a string, ends with "=="
    • every encrypted text ends with a "="

    One example of an output from my encryption: XbjwWH4ZA02KtH49/4IP9w==RxVDObmUzg3TJe0jWNuj8ZqDwK4zc8n0o4KCsXV1478=

    Isn't this painfully obvious? I look at this and I know exactly where the IV ends and the encrypted string begins. If every record in the DB looks like this, then it's obvious that the first part is the IV, if you notice the fixed size and are aware of standard implementations.

    Also, I'm not sure the ending with a "=" won't give away more.

    Why does this happen? Is it my fault for converting the byte array? Shouldn't I be worried about these patterns being a possible security weakness?



  • Isn't this painfully obvious? I look at this and I know exactly where the IV ends and the encrypted string begins.

    That's OK. The IV is not a secret, and an attacker does not gain any advantage by knowing which bytes in the payload contain the IV and which bytes contain the ciphertext. With other encryption tools, it is well-known how the IV is stored along with the ciphertext - especially if the encryption tool is open-source, and anyone can simply look at the code to see how its done. See https://crypto.stackexchange.com/questions/3298/is-there-a-standard-for-openssl-interoperable-aes-encryption for how openssl does it.

    Also, I'm not sure the ending with a "=" won't give away more.

    Remember, your IV and your ciphertext are raw bytes. You are base64-encoding these raw bytes, so that they can be represented as displayable text. Base64-encoded text must have a length that is a multiple of 4. The '=' symbols that you are seeing is padding, to pad the length to a multiple of 4 if needed. Again, this is not revealing anything useful to an attacker.

    If you don't like having the '=' symbols between your IV and your ciphertext, just concatenate the raw bytes of your IV with the raw bytes of your ciphertext first, then base64-encode the result of that.



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2