I need to create a .netstandard2.0
C# library that derives a symmetric key from a password. Therefore, I cannot use many of new, fancy classes that Microsoft provides, and need to stick with PasswordDeriveBytes
.
My PoC quite followed the one in the documentation:
// use .netstandard2.0 kdf to derive the key
int kdfIterations = 10000;
// some random values
var salt = new byte[] { 18, 25, 36, 78, 96, 174, 56, 96, 47, 12, 13, 14, 47, 47, 36, 49 };
var iv = new byte[] { 17, 6, 9, 53, 207, 8, 0, 16, 47, 89, 44, 22, 33, 44, 77, 15 };
byte[] key = iv;
var passwordDeriveBytes = new PasswordDeriveBytes("mySuperSecretPassword", salt);
for (int i = 0; i < kdfIterations; i++)
{
key = passwordDeriveBytes.CryptDeriveKey("TripleDES", "SHA256", 192, key.Take(8).ToArray());
}
But as a matter of fact I have revealed that when I swap salt
and iv
, the derived key value stays the same. Bummer. This answer provides an explanation that salt
is not used indeed. But when you play with it, you realize that iv
value to the CryptDeriveKey()
actually does not matter either, whatever the number of kdfIterations
, the result does not change. In other words, derived key only depends on the password itself. That seems like very crappy implementation indeed. Is that true or am I missing something?
I can come up with a workaround like
// use .netstandard2.0 kdf to derive the key
int kdfIterations = 10000;
// some random values
var salt = new byte[] { 18, 25, 36, 78, 96, 174, 56, 96, 47, 12, 13, 14, 47, 47, 36, 49 };
var iv = new byte[] { 17, 6, 9, 53, 207, 8, 0, 16, 47, 89, 44, 22, 33, 44, 77, 15 };
byte[] key = iv;
for (int i = 0; i < kdfIterations; i++)
{
using var passwordDeriveBytes = new PasswordDeriveBytes($"{Convert.ToBase64String(key)}mySuperSecretPassword{Convert.ToBase64String(salt)}", salt);
key = passwordDeriveBytes.CryptDeriveKey("TripleDES", "SHA256", 192, key.Take(8).ToArray());
}
which already takes salt
, iv
and kdfIterations
into account, but I believe the documentation should actually warn that iv
and salt
are there just showcasing. Which is incredible for me, as I majored in cryptography.