Please help me. I want to encrypt using AES-GCM algorithm in C# code.
Here is my code – however, it can not decrypt. I want to keep the decryption code intact.
How to solve this problem? Please help me.
<code>// Encryption code.
private static byte[] salt = new byte[16]; // Fix 1: consider salt
private static byte[] iv = new byte[12];
private const int iterations = 100000; // Fix 2: apply the same iteration count
public string Encrypt(string key, string data)
byte[] tag = new byte[16];
using (var rng = RandomNumberGenerator.Create())
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
byte[] privateKey = DeriveKey(key);
using (AesGcm aes = new AesGcm(privateKey, tag.Length))
byte[] encrypted = new byte[dataBytes.Length];
aes.Encrypt(iv, dataBytes, encrypted, tag);
byte[] combinedBuffer = new byte[salt.Length + iv.Length + encrypted.Length];
Buffer.BlockCopy(salt, 0, combinedBuffer, 0, salt.Length); // Fix 1: consider salt
Buffer.BlockCopy(iv, 0, combinedBuffer, salt.Length, iv.Length);
Buffer.BlockCopy(encrypted, 0, combinedBuffer, salt.Length + iv.Length, encrypted.Length);
string base64Buff = BuffToBase64(combinedBuffer);
public static byte[] DeriveKey(string password)
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
using (var pbkdf2 = new Rfc2898DeriveBytes(passwordBytes, salt, iterations, HashAlgorithmName.SHA256))
byte[] key = pbkdf2.GetBytes(32); // Fix 3: use the same key size (256 bits)
public static string BuffToBase64(byte[] buff)
return Convert.ToBase64String(buff);
public static byte[] Base64ToBuff(string b64)
return Convert.FromBase64String(b64);
public string Decrypt(string password, string encryptedString)
Span<byte> encryptedData = Convert.FromBase64String(encryptedString).AsSpan();
Span<byte> salt = encryptedData[..16];
Span<byte> nonce = encryptedData[16..(16 + 12)];
Span<byte> data = encryptedData[(16 + 12)..^16];
Span<byte> tag = encryptedData[^16..];
using Rfc2898DeriveBytes pbkdf2 = new(Encoding.UTF8.GetBytes(password), salt.ToArray(), 100000, HashAlgorithmName.SHA256);
using AesGcm aes = new(pbkdf2.GetBytes(32), tag.Length);
Span<byte> result = new byte[data.Length];
aes.Decrypt(nonce, data, tag, result);
return Encoding.UTF8.GetString(result);
var r = new AesGcmEncryption().Encrypt("my passphrase", "abcd");
var r2 = new AesGcmEncryption().Decrypt("my passphrase", r);
<code>// Encryption code.
private static byte[] salt = new byte[16]; // Fix 1: consider salt
private static byte[] iv = new byte[12];
private const int iterations = 100000; // Fix 2: apply the same iteration count
public string Encrypt(string key, string data)
{
byte[] tag = new byte[16];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
rng.GetBytes(iv);
}
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
byte[] privateKey = DeriveKey(key);
using (AesGcm aes = new AesGcm(privateKey, tag.Length))
{
byte[] encrypted = new byte[dataBytes.Length];
aes.Encrypt(iv, dataBytes, encrypted, tag);
byte[] combinedBuffer = new byte[salt.Length + iv.Length + encrypted.Length];
Buffer.BlockCopy(salt, 0, combinedBuffer, 0, salt.Length); // Fix 1: consider salt
Buffer.BlockCopy(iv, 0, combinedBuffer, salt.Length, iv.Length);
Buffer.BlockCopy(encrypted, 0, combinedBuffer, salt.Length + iv.Length, encrypted.Length);
string base64Buff = BuffToBase64(combinedBuffer);
return base64Buff;
}
}
public static byte[] DeriveKey(string password)
{
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
using (var pbkdf2 = new Rfc2898DeriveBytes(passwordBytes, salt, iterations, HashAlgorithmName.SHA256))
{
byte[] key = pbkdf2.GetBytes(32); // Fix 3: use the same key size (256 bits)
return key;
}
}
public static string BuffToBase64(byte[] buff)
{
return Convert.ToBase64String(buff);
}
public static byte[] Base64ToBuff(string b64)
{
return Convert.FromBase64String(b64);
}
// Decryption code
public string Decrypt(string password, string encryptedString)
{
Span<byte> encryptedData = Convert.FromBase64String(encryptedString).AsSpan();
Span<byte> salt = encryptedData[..16];
Span<byte> nonce = encryptedData[16..(16 + 12)];
Span<byte> data = encryptedData[(16 + 12)..^16];
Span<byte> tag = encryptedData[^16..];
using Rfc2898DeriveBytes pbkdf2 = new(Encoding.UTF8.GetBytes(password), salt.ToArray(), 100000, HashAlgorithmName.SHA256);
using AesGcm aes = new(pbkdf2.GetBytes(32), tag.Length);
Span<byte> result = new byte[data.Length];
aes.Decrypt(nonce, data, tag, result);
return Encoding.UTF8.GetString(result);
}
// Run the program.
var r = new AesGcmEncryption().Encrypt("my passphrase", "abcd");
var r2 = new AesGcmEncryption().Decrypt("my passphrase", r);
Console.WriteLine(r);
Console.WriteLine(r2);
</code>
// Encryption code.
private static byte[] salt = new byte[16]; // Fix 1: consider salt
private static byte[] iv = new byte[12];
private const int iterations = 100000; // Fix 2: apply the same iteration count
public string Encrypt(string key, string data)
{
byte[] tag = new byte[16];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
rng.GetBytes(iv);
}
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
byte[] privateKey = DeriveKey(key);
using (AesGcm aes = new AesGcm(privateKey, tag.Length))
{
byte[] encrypted = new byte[dataBytes.Length];
aes.Encrypt(iv, dataBytes, encrypted, tag);
byte[] combinedBuffer = new byte[salt.Length + iv.Length + encrypted.Length];
Buffer.BlockCopy(salt, 0, combinedBuffer, 0, salt.Length); // Fix 1: consider salt
Buffer.BlockCopy(iv, 0, combinedBuffer, salt.Length, iv.Length);
Buffer.BlockCopy(encrypted, 0, combinedBuffer, salt.Length + iv.Length, encrypted.Length);
string base64Buff = BuffToBase64(combinedBuffer);
return base64Buff;
}
}
public static byte[] DeriveKey(string password)
{
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
using (var pbkdf2 = new Rfc2898DeriveBytes(passwordBytes, salt, iterations, HashAlgorithmName.SHA256))
{
byte[] key = pbkdf2.GetBytes(32); // Fix 3: use the same key size (256 bits)
return key;
}
}
public static string BuffToBase64(byte[] buff)
{
return Convert.ToBase64String(buff);
}
public static byte[] Base64ToBuff(string b64)
{
return Convert.FromBase64String(b64);
}
// Decryption code
public string Decrypt(string password, string encryptedString)
{
Span<byte> encryptedData = Convert.FromBase64String(encryptedString).AsSpan();
Span<byte> salt = encryptedData[..16];
Span<byte> nonce = encryptedData[16..(16 + 12)];
Span<byte> data = encryptedData[(16 + 12)..^16];
Span<byte> tag = encryptedData[^16..];
using Rfc2898DeriveBytes pbkdf2 = new(Encoding.UTF8.GetBytes(password), salt.ToArray(), 100000, HashAlgorithmName.SHA256);
using AesGcm aes = new(pbkdf2.GetBytes(32), tag.Length);
Span<byte> result = new byte[data.Length];
aes.Decrypt(nonce, data, tag, result);
return Encoding.UTF8.GetString(result);
}
// Run the program.
var r = new AesGcmEncryption().Encrypt("my passphrase", "abcd");
var r2 = new AesGcmEncryption().Decrypt("my passphrase", r);
Console.WriteLine(r);
Console.WriteLine(r2);
Error:
Specified argument was out of the range of valid values
I tried changing all the cases, by changing the code, and searched but no one wrote similar code.