2

I'm using the following code to generate an encryption salt.

TripleDES tripleDES = TripleDES.Create()
tripleDES.IV = new byte[8];

using (RNGCryptoServiceProvider rngProvider = new RNGCryptoServiceProvider())
{
    rngProvider.GetBytes(tripleDES.IV);
}

Rfc2898DeriveBytes keyBytes = new Rfc2898DeriveBytes(Password, tripleDES.IV);
tripleDES.Key = keyBytes.GetBytes(16);

But after calling GetBytes(), I can see that tripleDES.IV contains all zeros.

That certainly doesn't seem as random as the documentation suggests.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466

1 Answers1

3

Looking at the source for SymmetricAlgorithm (the base class for TripleDES), the IV property returns a clone of the current IV byte array, so rngProvider.GetBytes() is setting the bytes on a clone array, not the actual one.

You don't need to set the IV to a random value anyway - it will be initialized to one already after calling TripleDES.Create(). And if you want a new one for some reason, you can just call GenerateIV() which will set IV to a new random value.

nollidge
  • 2,192
  • 12
  • 13
  • Did you read the source code I linked? Look at the `IV` property – nollidge Mar 05 '20 at 21:41
  • 3
    What nollidge is saying is that if you use `tripleDES.IV` the way you've specified, you are using the **getter** of the property, not the setter. That getter makes a copy and returns that as value. This copy is then randomized by you, and then garbage collected right after that. If you want to set the property manually, then you need to create a byte array, randomize it and then **assign it** to the property. That way the setter is used. But as nollidge mentions, that is hardly necessary because the IV will be randomized by default - for this specific part of the .NET framework anyway. – Maarten Bodewes Mar 05 '20 at 23:39
  • I.e. first encrypt, and then get the IV, it should be randomized. – Maarten Bodewes Mar 05 '20 at 23:44