2

is it possible to use random salt and random iv in encryption and decryption algorithm using AES or RijndaelManaged?

I was learning about encryption and decryption algorithms, I tried using aes or rijndaelmanaged in C#, someone else said, if you use a static salt for encryption and reuses the IV it won't be safe.

Encryption

public static byte[] encryptAES(byte[] bytesToBeEncrypted, byte[] 
passwordBytes)
{
byte[] result = null;
byte[] salt = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream MS = new MemoryStream())
{
using (RijndaelManaged Rima = new RijndaelManaged())
{
Rima.KeySize = 256;
Rima.BlockSize = 128;
Rfc2898DeriveBytes RFCDB = new Rfc2898DeriveBytes(passwordBytes, salt, 
1000);
Rima.Key = RFCDB.GetBytes(Rima.KeySize / 8);
Rima.IV = RFCDB.GetBytes(Rima.BlockSize / 8);
Rima.Mode = CipherMode.CBC;
using (CryptoStream CS = new CryptoStream(MS, Rima.CreateEncryptor(), 
CryptoStreamMode.Write))
{
CS.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
CS.Close();
}
result = MS.ToArray();
}
}
return result;
}

Decryption

public static byte[] decryptAES(byte[] bytesToBeDecrypted, byte[] 
passwordBytes)
{
byte[] result = null;
using (MemoryStream memoryStream = new MemoryStream())
{
Rfc2898DeriveBytes rfc2898DeriveBytes = new 
Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
Rima.Key = rfc2898DeriveBytes.GetBytes(Rima.KeySize / 8);
Rima.IV = rfc2898DeriveBytes.GetBytes(Rima.BlockSize / 8);
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, 
Rima.CreateDecryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cryptoStream.Close();
}
result = memoryStream.ToArray();
}
return result;
}

private static RijndaelManaged Rima = new RijndaelManaged
{
KeySize = 256,
BlockSize = 128,
Mode = CipherMode.CBC
};

private static byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

I tried to find a way to use random or dynamic salt and random IV.

Community
  • 1
  • 1
Nurohman AR
  • 75
  • 1
  • 11
  • 1
    RijndaelManaged is a very old library and non-standard. The standard is AES and you should use [AesCryptoServiceProvide](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.aescryptoserviceprovider?view=netframework-4.7.2). Forget about CBC mode of operation use AES-GCM or ChaCha-Poly1305 which are [authenticated encryption](https://en.wikipedia.org/wiki/Authenticated_encryption) modes included in TLS 1.3. – kelalaka Apr 06 '19 at 07:47

1 Answers1

2

Yes...it's a bad idea to use static IV or salt. The reason is that using a consistent IV or salt has a "tell" or a consistent effect on all the messages you send using that IV and salt. For all practical purposes, you can generate a random salt and IV, but, the decryptor needs to know the values for them. Technically, they're not secret, and you can send them to the recipient. If they're being used to encrypt data held in a database, you need to keep the salt and IV with the message.

In block ciphers, they're used to "mask" the start of the message so that you won't see recurring patterns in the ciphertext. If you use the same salt and IV on all your messages (assuming you're using the same password or key), every message that starts with the same few characters will have the same few bytes in the start of the ciphertext...and therein lies the beginning of the sniffing out of your messages. Bits of the first block are fed back into the next block of ciphertext...so a random first few chunks of message more completely scrambles your messages...making pattern analysis far more difficult.

BTW, you're using some old code from old examples. I recommend that you have a look at this question for more appropriate ways of encrypting/decrypting data in .Net. You'll see some code in some of the answers that look a lot like what you have, but there are important differences. The discussions in this question and the top answers are worth a read.

Clay
  • 4,999
  • 1
  • 28
  • 45