Trying to understand why the padding is invalid in this AES method - c#

I'm in the middle of porting an older application to .Net 6, and have hit a stumbling block of the encryption / decryption method is now failing. It still works perfectly fine under .Net 4.x.x.
The error being thrown is,
"Padding is invalid and cannot be removed."
Code: - Updated to actual original code. This code worked fine when targeting .Net 4.7.2, however after moving the code to .Net 6.0 RC2, it started to lose anything greater than 32 chars of the decrypted string, which lead to errors elsewhere as the strings weren't complete.
For context. This was running on a webhost & a desktop client, to encrypt messages in transit. The webhost has been updated and validated to be sending the correct encrypted value (decrypting the message using the .Net 4 client is successful). However, the .Net 6 desktop client isn't decrypting it correctly and is losing characters in the decrypted string.
#region Encrypt method(s)
private const int Keysize = 256;
private const int Blocksize = 128;
private const int DerivationIterations = 1000;
public async Task<string> EncryptStringWithValidatedPadding(string plainText, string passPhrase)
{
string encrypted = null;
bool valid = false;
while (!valid)
{
encrypted = await Encrypt(plainText, passPhrase);
if (!string.IsNullOrEmpty(await Decrypt(encrypted, passPhrase)))
{
valid = true;
}
}
return encrypted;
}
private async Task<string> Encrypt(string plainText, string passPhrase)
{
var saltStringBytes = GenerateRandomEntropy(32); // 256 bits
var ivStringBytes = GenerateRandomEntropy(16); // 128 bits
byte[] plainTextBytes = Convert.FromBase64String(plainText);
using (var password = new Rfc2898DeriveBytes(Convert.FromBase64String(passPhrase), saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var symmetricKey = new AesManaged())
{
symmetricKey.KeySize = Keysize;
symmetricKey.BlockSize = Blocksize;
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
var cipherTextBytes = saltStringBytes;
cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
memoryStream.Close();
cryptoStream.Close();
var encrypted64String = Convert.ToBase64String(cipherTextBytes);
return encrypted64String;
}
}
}
}
}
}
private static byte[] GenerateRandomEntropy(int byteSize)
{
var randomBytes = new byte[byteSize];
using (var rngCsp = new RNGCryptoServiceProvider())
{
rngCsp.GetBytes(randomBytes);
}
return randomBytes;
}
#endregion
#region Decrypt method
public static async Task<string> Decrypt(string cipherText, string passPhrase)
{
try
{
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Blocksize / 8).ToArray();
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) + Blocksize / 8).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) + Blocksize / 8)).ToArray();
using (var password = new Rfc2898DeriveBytes(Convert.FromBase64String(passPhrase), saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var symmetricKey = new AesManaged())
{
symmetricKey.KeySize = 256;
symmetricKey.BlockSize = Blocksize;
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream(cipherTextBytes))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
var plainTextBytes = new byte[cipherTextBytes.Length];
var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
}
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return null;
}
#endregion
This is called with,
encryptedString = await new EncryptDecrypt().EncryptStringWithValidatedPadding(b64String, Convert.ToBase64String(Encoding.UTF8.GetBytes(passPhrase)));
I am assuming that saving the IV should solve this, but I'm wondering if there are any obvious flaws here that I'm just not seeing.
Can anyone explain it?
Update: As suggested I've refactored the code to the below. I've also stripped it right back for the minute to ensure the underlying algo's work.
Ref: https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.aes?view=net-6.0
namespace Encryption_Helper
{
public class EncryptDecrypt
{
#region Encrypt method(s)
private static byte[] bytes = new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 };
private const int Keysize = 256;
private const int Blocksize = 128;
private const int DerivationIterations = 1000;
public static async Task<string> EncryptStringWithValidatedPadding(string plainText, string passPhrase)
{
string encrypted = null;
bool valid = false;
while (!valid)
{
encrypted = await Encrypt(plainText, passPhrase);
if (!string.IsNullOrEmpty(await Decrypt(encrypted, passPhrase)))
{
valid = true;
}
}
return encrypted;
}
private static async Task<string> Encrypt(string plainText, string passPhrase)
{
using (var password = new Rfc2898DeriveBytes(Convert.FromBase64String(passPhrase), bytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
var ivBytes = password.GetBytes(Blocksize / 8);
using (var aes = Aes.Create())
{
aes.Key = keyBytes;
aes.IV = ivBytes;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
plainText = Convert.ToBase64String(msEncrypt.ToArray());
}
}
}
return plainText;
}
}
#endregion
#region Decrypt method
public static async Task<string> Decrypt(string cipherText, string passPhrase)
{
try
{
using (var password = new Rfc2898DeriveBytes(Convert.FromBase64String(passPhrase), bytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
var ivBytes = password.GetBytes(Blocksize / 8);
using (var aes = Aes.Create())
{
aes.Key = keyBytes;
aes.IV = ivBytes;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (var memoryStream = new MemoryStream(Convert.FromBase64String(cipherText)))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(cryptoStream))
{
cipherText = srDecrypt.ReadToEnd();
}
}
}
return cipherText;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
#endregion
}
}
It is still throwing a padding error!

Solved it!
public class EncryptDecrypt
{
#region Encrypt method(s)
private const int Keysize = 256;
private const int Blocksize = 128;
private const int DerivationIterations = 1000;
public static async Task<string> EncryptStringWithValidatedPadding(string plainText, string passPhrase)
{
string encrypted = null;
bool valid = false;
while (!valid)
{
encrypted = await Encrypt(plainText, passPhrase);
if (!string.IsNullOrEmpty(await Decrypt(encrypted, passPhrase)))
{
valid = true;
}
}
return encrypted;
}
private static async Task<string> Encrypt(string plainText, string passPhrase)
{
var saltStringBytes = GenerateRandomEntropy(Keysize / 8); // 256 bits
var ivStringBytes = GenerateRandomEntropy(Blocksize / 8); // 128 bits
byte[] plainTextBytes = Convert.FromBase64String(plainText);
using (var password = new Rfc2898DeriveBytes(Convert.FromBase64String(passPhrase), saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var aes = Aes.Create())
{
aes.KeySize = Keysize;
aes.BlockSize = Blocksize;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(keyBytes, ivStringBytes), CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
var cipherTextBytes = saltStringBytes;
cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
memoryStream.Close();
cryptoStream.Close();
var encrypted64String = Convert.ToBase64String(cipherTextBytes);
return encrypted64String;
}
}
}
}
}
private static byte[] GenerateRandomEntropy(int byteSize)
{
var randomBytes = new byte[byteSize];
using (var rngCsp = new RNGCryptoServiceProvider())
{
rngCsp.GetBytes(randomBytes);
}
return randomBytes;
}
#endregion
#region Decrypt method
public static async Task<string> Decrypt(string cipherText, string passPhrase)
{
try
{
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Blocksize / 8).ToArray();
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) + Blocksize / 8).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) + Blocksize / 8)).ToArray();
using (var password = new Rfc2898DeriveBytes(Convert.FromBase64String(passPhrase), saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var aes = Aes.Create())
{
aes.KeySize = Keysize;
aes.BlockSize = Blocksize;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using (var ms = new MemoryStream(cipherTextBytes))
{
using (var cs = new CryptoStream(ms, aes.CreateDecryptor(keyBytes, ivStringBytes), CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(cs))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
cipherText = srDecrypt.ReadToEnd();
}
}
}
return cipherText;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return null;
}
#endregion
After updating the decryption method, all's good in the world again.
It appears to me that .Net 6 broke the nested using loops, closing the stream before the return value was completely set.

Related

AES 256 block size only part of the string is decrypted

I am trying to implement a .net core version of our existing encryption mechanism. my existing encryption is implemented in the below way which is not compatible with .net core
byte[] bytesToBeDecrypted = Convert.FromBase64String(dataToDecrypt);
byte[] saltBytes = new byte[16];
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 256;
var key = new Rfc2898DeriveBytes(GetHashKeyWithSHA256(), saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
AES.Padding = PaddingMode.PKCS7;
using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.Close();
}
return UTF8Encoding.UTF8.GetString(ms.ToArray());
}
}
But there is no direct method to implement this into .net core so i have used AES but it is giving always a portion of expected output
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
byte[] saltBytes = new byte[16];
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
using (var password = new Rfc2898DeriveBytes(GetHashKeyWithSHA256(), saltBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
var engine = new RijndaelEngine(256);
var blockCipher = new CbcBlockCipher(engine);
var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
var keyParam = new KeyParameter(keyBytes);
var keyParamWithIV = new ParametersWithIV(keyParam, ivStringBytes, 0, 32);
cipher.Init(false, keyParamWithIV);
var comparisonBytes = new byte[cipher.GetOutputSize(cipherTextBytes.Length)];
var length = cipher.ProcessBytes(cipherTextBytes, comparisonBytes, 0);
cipher.DoFinal(comparisonBytes, length);
var nullIndex = comparisonBytes.Length - 1;
while (comparisonBytes[nullIndex] == (byte)0)
nullIndex--;
comparisonBytes = comparisonBytes.Take(nullIndex + 1).ToArray();
var result = Encoding.UTF8.GetString(comparisonBytes, 0, comparisonBytes.Length);
return result;
}
private static byte[] GetHashKeyWithSHA256()
{
string key = "2893562938q562bdx3whegujfgwehjgfewygfr3287t4238rb2332r7y234723byr54h";
byte[] passwordBytes = Encoding.UTF8.GetBytes(key);
return SHA256.Create().ComputeHash(passwordBytes);
}
Test Input : SxXrRvUEqYvRATVswgrJVQ9EtS6AHJVo6wV+mhQpW+t9a0GPDxvatC9JUYEJ5z/vrPD0MBxyW3dBfrlgec2LqA==
Appreciate if somebody helps me to identify the issue
In the 2nd snippet there are the following issues:
dataToDecrypt contains only the ciphertext but not salt and IV. Therefore no separation is necessary.
Key and (especially) IV must be derived using the key derivation as in the 1st snippet.
The returned length in the DoFinal() call must be taken into account and used in the later GetString() call.
A possible implementation is:
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
using System;
using System.Security.Cryptography;
using System.Text;
...
string dataToDecrypt = "SxXrRvUEqYvRATVswgrJVQ9EtS6AHJVo6wV+mhQpW+t9a0GPDxvatC9JUYEJ5z/vrPD0MBxyW3dBfrlgec2LqA==";
var cipherTextBytes = Convert.FromBase64String(dataToDecrypt);
byte[] saltBytes = new byte[16];
int DerivationIterations = 1000;
using (var key = new Rfc2898DeriveBytes(GetHashKeyWithSHA256(), saltBytes, DerivationIterations))
{
var keyBytes = key.GetBytes(256 / 8);
var ivBytes = key.GetBytes(256 / 8);
var engine = new RijndaelEngine(256);
var blockCipher = new CbcBlockCipher(engine);
var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
var keyParam = new KeyParameter(keyBytes);
var keyParamWithIV = new ParametersWithIV(keyParam, ivBytes, 0, 32);
cipher.Init(false, keyParamWithIV);
var comparisonBytes = new byte[cipher.GetOutputSize(cipherTextBytes.Length)];
var length = cipher.ProcessBytes(cipherTextBytes, comparisonBytes, 0);
length += cipher.DoFinal(comparisonBytes, length);
Console.WriteLine(Encoding.UTF8.GetString(comparisonBytes, 0, length)); // hello .thanks for helping me to resolve the issue
}
With this a decryption is possible with the posted test data: hello .thanks for helping me to resolve the issue
Keep in mind that a static salt is insecure. Instead, a random salt should be generated for each encryption. The salt is not secret and is passed along with the ciphertext to the decrypting side, typically concatenated.
Edit:
As requested in the comment, the related encryption is:
string dataToEncrypt = "hello .thanks for helping me to resolve the issue ";
var plainTextBytes = Encoding.UTF8.GetBytes(dataToEncrypt);
byte[] saltBytes = new byte[16];
int DerivationIterations = 1000;
using (var key = new Rfc2898DeriveBytes(GetHashKeyWithSHA256(), saltBytes, DerivationIterations))
{
var keyBytes = key.GetBytes(256 / 8);
var ivBytes = key.GetBytes(256 / 8);
var engine = new RijndaelEngine(256);
var blockCipher = new CbcBlockCipher(engine);
var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
var keyParam = new KeyParameter(keyBytes);
var keyParamWithIV = new ParametersWithIV(keyParam, ivBytes, 0, 32);
cipher.Init(true, keyParamWithIV);
var ciphertextBytes = new byte[cipher.GetOutputSize(plainTextBytes.Length)];
var length = cipher.ProcessBytes(plainTextBytes, ciphertextBytes, 0);
cipher.DoFinal(ciphertextBytes, length);
Console.WriteLine(Convert.ToBase64String(ciphertextBytes)); // SxXrRvUEqYvRATVswgrJVQ9EtS6AHJVo6wV+mhQpW+t9a0GPDxvatC9JUYEJ5z/vrPD0MBxyW3dBfrlgec2LqA==
}
You can try this:
private const string Key = "ffs-Jks*ca#cyY<xHR][Ycx{dDL,B_nJeOgFa'G_q^Hv.yDWq.dsbE'1af^xdeP";
private static readonly byte[] IV = { 11, 123, 1, 44, 78, 22, 54, 12 };
#endregion
#region methods
/// <summary>
/// Creates a symmetric decryptor object with the current Key property and initialization vector (IV).
/// </summary>
/// <param name="cipherText">The encrypted string.</param>
/// <returns>The Plaintext of an encrypted string.</returns>
public static string Decrypt(string cipherText)
{
try
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
{
//TODO:LogErrors.Error(new ArgumentNullException("cipherText"));
return null;
}
if (Key == null || Key.Length <= 0)
{
//TODO:LogErrors.Error(new ArgumentNullException("Key"));
return null;
}
if (IV == null || IV.Length <= 0)
{
//TODO:LogErrors.Error(new ArgumentNullException("IV"));
return null;
}
cipherText = cipherText.Replace(" ", "+");
var cipherBytes = Convert.FromBase64String(cipherText);
using var encryptor = Aes.Create();
var pdb = new Rfc2898DeriveBytes(Key, IV);
encryptor.Mode = CipherMode.CBC;
encryptor.KeySize = 128;
encryptor.BlockSize = 128;
encryptor.FeedbackSize = 128;
encryptor.Padding = PaddingMode.PKCS7;
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using var ms = new MemoryStream();
using (var cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
cipherText = cipherText.TrimEnd(char.Parse("\0"));
return cipherText;
}
catch (ArgumentNullException ex)
{
//TODO:LogErrors.Error(ex);
}
catch (ArgumentException ex)
{
//TODO:LogErrors.Error(ex);
}
catch (FormatException ex)
{
//TODO:LogErrors.Error(ex);
}
catch (CryptographicException ex)
{
//TODO:LogErrors.Error(ex);
}
catch (NotSupportedException ex)
{
//TODO:LogErrors.Error(ex);
}
return null;
}
/// <summary>
/// Creates a symmetric encryptor object with the current Key property and initialization vector (IV).
/// </summary>
/// <param name="clearText">The plaintext or string to be encrypted.</param>
/// <returns>The encrypted string.</returns>
public static string Encrypt(string clearText)
{
try
{
// Check arguments.
if (clearText == null || clearText.Length <= 0)
{
//TODO:LogErrors.Error(new ArgumentNullException("plainText"));
return null;
}
if (Key == null || Key.Length <= 0)
{
//TODO:LogErrors.Error(new ArgumentNullException("Key"));
return null;
}
if (IV == null || IV.Length <= 0)
{
//TODO:LogErrors.Error(new ArgumentNullException("IV"));
return null;
}
var clearBytes = Encoding.Unicode.GetBytes(clearText);
using var encryptor = Aes.Create();
var pdb = new Rfc2898DeriveBytes(Key, IV);
encryptor.Mode = CipherMode.CBC;
encryptor.KeySize = 128;
encryptor.BlockSize = 128;
encryptor.FeedbackSize = 128;
encryptor.Padding = PaddingMode.PKCS7;
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using var ms = new MemoryStream();
using (var cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
return clearText;
}
catch (EncoderFallbackException ex)
{
//TODO:LogErrors.Error(ex);
}
catch (ArgumentNullException ex)
{
//TODO:LogErrors.Error(ex);
}
catch (ArgumentException ex)
{
//TODO:LogErrors.Error(ex);
}
catch (CryptographicException ex)
{
//TODO:LogErrors.Error(ex);
}
catch (NotSupportedException ex)
{
//TODO:LogErrors.Error(ex);
}
catch (OverflowException ex)
{
//TODO:LogErrors.Error(ex);
}
return null;
}
I'd start much closer to your original code with,
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
public static class Crypto
{
public static string Decrypt(string dataToDecrypt)
{
byte[] bytesToBeDecrypted = Convert.FromBase64String(dataToDecrypt);
byte[] saltBytes = new byte[16];
using (MemoryStream ms = new MemoryStream())
{
using (Aes AES = Aes.Create())
{
AES.KeySize = 256;
AES.BlockSize = 256;
var key = new Rfc2898DeriveBytes(GetHashKeyWithSHA256(), saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
AES.Padding = PaddingMode.PKCS7;
using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.Close();
}
return UTF8Encoding.UTF8.GetString(ms.ToArray());
}
}
}
}
First get it work, then improve it.

C# AES Encryption Need

I have an Encrypted string and function to decrypt it. Now I need to edit this string and encrypt it. When I use this function to encrypt and decrypt in result strings are not the same.
Orginal encrypted string:
APpuC6G3f3cUKaAuOFXOGIo9rwz/+fQ0tBCi6Fk40THVnIT+au7JXkOQHdgPcpQ3VUrXw69rIL+QRsHea5+Q6TxOeuAnzkU8c3UClx6Toe+jOIVi3DlkLIGzE8DmyBArtZYpKTOt4rrOSDyLKifdgcM+MgwuJbDXyXVuQyp2C42zZ1ETPUOF2TSIZKhnMSR43FFy8WEbpKBAjkPmgVpqqhrjabu+JHbj7kPIxGGjDHGaCCyCtFwsk3264Lv4GTp049SCjNNYV0NVcN4wV0MaWMEO0iLuNGkseHuu5Snvp3YzZfXxDBWSLOUXc2zeXL2tA6So9WA5P3lZ/ga5i366EQ==
Orginal encrypted string after decrypt:
{"status":"PASS","data":{"map_path":"VOtKu0.yGT","file_extension":"KAmXWV","username":"damianek","timestamp":9999999999},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}
Orginal decrypt function:
public static string Decypher(string var1)
{
var1 = var1.Trim();
byte[] array = Convert.FromBase64String(var1);
byte[] array2 = new byte[16];
byte[] array3 = new byte[32];
byte[] array4 = new byte[array.Length - 48];
for (int i = 0; i < 16; i++)
{
array2[i] = array[i];
}
for (int j = 16; j < 48; j++)
{
array3[j - 16] = array[j];
}
for (int k = 48; k < array.Length; k++)
{
array4[k - 48] = array[k];
}
ivv = array2;
Aes aes = Aes.Create();
aes.Mode = CipherMode.CBC;
aes.Key = GetToken();
aes.IV = array2;
MemoryStream memoryStream = new MemoryStream();
ICryptoTransform transform = aes.CreateDecryptor();
CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
string result = string.Empty;
try
{
cryptoStream.Write(array4, 0, array4.Length);
cryptoStream.FlushFinalBlock();
byte[] array5 = memoryStream.ToArray();
result = Encoding.ASCII.GetString(array5, 0, array5.Length);
memoryStream.Close();
cryptoStream.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace);
}
return result;
}
My encrypt function:
public void EncryptStringToBytes()
{
string plainText = textBox2.Text;
byte[] array = Encoding.UTF8.GetBytes(plainText);
byte[] encrypted;
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = GetToken();
aesAlg.IV = new byte[16];
aesAlg.Mode = CipherMode.CBC;
var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
textBox3.Text = Convert.ToBase64String(encrypted);
}
String after my encrypt & decrypt with orginal function:
?%j>]???r?????":"KAmXWV","username":"damianek","timestamp":1637955589},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}
EDIT:
Now encrypt function look:
public void EncryptStringToBytes()
{
string plainText = textBox2.Text.Trim();
byte[] array = Encoding.ASCII.GetBytes(plainText);
byte[] encrypted;
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = GetToken();
aesAlg.IV = GetIV();
aesAlg.Mode = CipherMode.CBC;
var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (var msEncrypt = new MemoryStream())
{
msEncrypt.Write(aesAlg.Key, 0, aesAlg.Key.Length);
msEncrypt.Flush();
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(aesAlg.Key, 0, aesAlg.Key.Length);
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
textBox3.Text = Convert.ToBase64String(encrypted);
}
But string after encrypt & decrypt look:
;???En Dp??g???{"status":"PASS","data":{"map_path":"VOtKu0.yGT","file_extension":"KAmXWV","username":"damianek","timestamp":1637955589},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}
My C# AES implementation
from my answer AES Crypto C# compatible Java
The IV is randomized in every Encrypt process to get different output with same text and avoid to intruders/attackers get original text easily.
The default mode is CBC.
The encoding used is UTF-8. UTF-8 is the most widely used encoding on the web.
You can test/run this code on https://replit.com/#JomaCorpFX/AesCbcEncrypt#main.cs
The code
using System;
using System.Security.Cryptography;
using System.Text;
public enum HashAlgorithm
{
MD5,
SHA1,
SHA256,
SHA384,
SHA512
}
public class HashManager
{
public static byte[] ToRawHash(byte[] data, HashAlgorithm algorithm)
{
byte[] hash;
switch (algorithm)
{
case HashAlgorithm.MD5:
MD5 md5 = MD5.Create();
hash = md5.ComputeHash(data, 0, data.Length);
return hash;
case HashAlgorithm.SHA1:
SHA1Managed sha1 = new SHA1Managed();
hash = sha1.ComputeHash(data);
return hash;
case HashAlgorithm.SHA256:
SHA256Managed sha256 = new SHA256Managed();
hash = sha256.ComputeHash(data);
return hash;
case HashAlgorithm.SHA384:
SHA384Managed sha384 = new SHA384Managed();
hash = sha384.ComputeHash(data);
return hash;
case HashAlgorithm.SHA512:
SHA512Managed sha512 = new SHA512Managed();
hash = sha512.ComputeHash(data, 0, data.Length);
return hash;
default:
throw new ArgumentException("Invalid Algorithm");
}
}
}
public class AesManager
{
private const int MAX_IV_LENGTH = 16;
private const int MAX_KEY_LENGTH = 32;
private static byte[] GenerateValidKey(byte[] keyBytes)
{
byte[] ret = new byte[MAX_KEY_LENGTH];
byte[] hash = HashManager.ToRawHash(keyBytes, HashAlgorithm.SHA256);
Array.Copy(hash, ret, MAX_KEY_LENGTH);
return ret;
}
public static byte[] EncryptRaw(byte[] PlainBytes, byte[] Key)
{
AesManaged AesAlgorithm = new AesManaged()
{
Key = GenerateValidKey(Key)
};
AesAlgorithm.GenerateIV();
var Encrypted = AesAlgorithm.CreateEncryptor().TransformFinalBlock(PlainBytes, 0, PlainBytes.Length);
byte[] ret = new byte[Encrypted.Length + MAX_IV_LENGTH];
Array.Copy(Encrypted, ret, Encrypted.Length);
Array.Copy(AesAlgorithm.IV, 0, ret, ret.Length - MAX_IV_LENGTH, MAX_IV_LENGTH);
return ret;
}
public static byte[] DecryptRaw(byte[] CipherBytes, byte[] Key)
{
AesManaged AesAlgorithm = new AesManaged()
{
Key = GenerateValidKey(Key)
};
byte[] IV = new byte[MAX_IV_LENGTH];
Array.Copy(CipherBytes, CipherBytes.Length - MAX_IV_LENGTH, IV, 0, MAX_IV_LENGTH);
AesAlgorithm.IV = IV;
byte[] RealBytes = new byte[CipherBytes.Length - MAX_IV_LENGTH];
Array.Copy(CipherBytes, RealBytes, CipherBytes.Length - MAX_IV_LENGTH);
return AesAlgorithm.CreateDecryptor().TransformFinalBlock(RealBytes, 0, RealBytes.Length); ;
}
public static String EncryptToBase64(String Plaintext, String Key)
{
byte[] PlainBytes = Encoding.UTF8.GetBytes(Plaintext);
return Base64Manager.ToBase64(EncryptRaw(PlainBytes, Encoding.UTF8.GetBytes(Key)), false);
}
public static String DecryptFromBase64(String CipherText, String Key)
{
byte[] CiPherBytes = Base64Manager.Base64ToByteArray(CipherText);
byte[] Encrypted = DecryptRaw(CiPherBytes, Encoding.UTF8.GetBytes(Key));
return Encoding.UTF8.GetString(Encrypted, 0, Encrypted.Length);
}
}
public class Base64Manager
{
public static byte[] Base64ToByteArray(String base64)
{
return Convert.FromBase64String(base64);
}
public static String ToBase64(byte[] data, Boolean insertLineBreaks = default(Boolean))
{
return insertLineBreaks ? Convert.ToBase64String(data, Base64FormattingOptions.InsertLineBreaks) : Convert.ToBase64String(data);
}
}
public class Program
{
public static void Main()
{
Console.Write("Plain text: ");
string plainText = Console.ReadLine();
Console.Write("Password: ");
string password = Console.ReadLine();
string encrypted = AesManager.EncryptToBase64(plainText, password);
Console.WriteLine();
Console.WriteLine($"Password: {password}" );
Console.WriteLine();
Console.WriteLine($"Encrypted: {encrypted}");
Console.WriteLine();
Console.WriteLine($"Decrypted: {AesManager.DecryptFromBase64(encrypted, password)}");
Console.ReadLine();
}
}
Output

How can I encrypt text with aesKey and private cert in C#?

I created public and private keys (pem) with openSsl tool. I used commands:
openssl genrsa -out privatekey.pem 2048
openssl req -new -key privatekey.pem -x509 -days 3650 -out publiccert.pem
Then I generate aesKey:
byte[] GenerateAesKey()
{
var rnd = new RNGCryptoServiceProvider();
var b = new byte[16];
rnd.GetNonZeroBytes(b);
return b;
}
My method for encrypt data:
string CreateSecurePayload(byte[] aesKey)
{
object obj = new
{
contact = new
{
email = "myName#email.com",
firstName = "John",
lastName = "Doe"
}
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
var res = "";
using (Aes myRijndael = Aes.Create())
{
byte[] encrypted = EncryptStringToBytes(json, aesKey, myRijndael.IV);
res = Convert.ToBase64String(encrypted);
}
return res;
}
byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
byte[] encrypted;
using (Aes rijAlg = Aes.Create())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return encrypted;
}
And then I encrypt my aesKey with private key:
string SecureKey(byte[] aesKey)
{
byte[] plainTextBytes = aesKey;
AsymmetricCipherKeyPair keys;
FileStream fileStream = new FileStream("path/to/privatekey.pem", FileMode.Open);
using (var reader = new StreamReader(fileStream))
{
var pr = new PemReader(reader);
keys = (AsymmetricCipherKeyPair)pr.ReadObject();
}
var eng = new OaepEncoding(new RsaEngine());
eng.Init(true, keys.Private);
int length = plainTextBytes.Length;
int blockSize = eng.GetInputBlockSize();
var cipherTextBytes = new List<byte>();
for (int chunkPosition = 0;
chunkPosition < length;
chunkPosition += blockSize)
{
int chunkSize = Math.Min(blockSize, length - chunkPosition);
cipherTextBytes.AddRange(eng.ProcessBlock(
plainTextBytes, chunkPosition, chunkSize
));
}
return Convert.ToBase64String(cipherTextBytes.ToArray());
}
Call methods:
void Main()
{
var aesKey = GenerateAesKey();
var encryptData = Newtonsoft.Json.JsonConvert.SerializeObject(new
{
securePayload = CreateSecurePayload(aesKey),
secureKey = SecureKey(aesKey)
});
}
I have a problem. Service does not decrypt my data with public key. I upload public key earlier in service.
Could you help me? Thanks
And I have examples of how I can encrypt data but in other languages:
I got the example, but on JS. I think I have a problem with IV, because I don`t send it
Here is the class that help you to perform Encryption/Decryption:
public static class DecryptionHelper
{
private static string EncryptionDecryptionKey = "your_key";
public static string Encrypt(string Text)
{
//var key = GenerateKey();
var key = Encoding.UTF8.GetBytes(EncryptionDecryptionKey);
var plainText = Text;
var encryptedData = EncryptStringToBytes(key, plainText);
return Convert.ToBase64String(encryptedData);
}
public static string Decrypt(string Text)
{
//var key = GenerateKey();
var key = Encoding.UTF8.GetBytes(EncryptionDecryptionKey);
byte[] encryptedData = Convert.FromBase64String(Text);
var decryptedData = DecryptBytesToString(key, encryptedData);
return decryptedData;
}
private static string DecryptBytesToString(byte[] key, byte[] data)
{
// IV was prepended to the encrypted bytes so peel that off
Tuple<byte[], byte[]> splitResult = SplitByteArray(data);
byte[] iv = splitResult.Item1;
byte[] cipherText = splitResult.Item2;
// Declare the string used to hold the decrypted text.
string plaintext;
// Create an RijndaelManaged object
// with the specified key and IV.
using (var aes = CreateAes256Algorithm())
{
aes.Key = key;
aes.IV = iv;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
// Create the streams used for decryption.
using (var msDecrypt = new MemoryStream(cipherText))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
private static Tuple<byte[], byte[]> SplitByteArray(byte[] data)
{
byte[] first = new byte[16];
Buffer.BlockCopy(data, 0, first, 0, first.Length);
byte[] second = new byte[data.Length - first.Length];
Buffer.BlockCopy(data, first.Length, second, 0, second.Length);
return Tuple.Create(first, second);
}
private static byte[] GenerateKey()
{
using (var aes = CreateAes256Algorithm())
{
aes.GenerateKey();
return aes.Key;
}
}
private static RijndaelManaged CreateAes256Algorithm()
{
return new RijndaelManaged { KeySize = 256, BlockSize = 128 };
}
private static byte[] EncryptStringToBytes(byte[] key, string plainText)
{
byte[] encrypted;
byte[] iv;
// Create an RijndaelManaged object with the specified key and IV.
using (var aes = CreateAes256Algorithm())
{
aes.Key = key;
aes.GenerateIV();
iv = aes.IV;
// Create a encrytor to perform the stream transform.
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
// Create the streams used for encryption.
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
// convert stream to bytes
encrypted = msEncrypt.ToArray();
}
}
}
// Prepend the iV to the encrypted bytes
return CombineByteArrays(iv, encrypted);
}
private static byte[] CombineByteArrays(byte[] first, byte[] second)
{
byte[] ret = new byte[first.Length + second.Length];
Buffer.BlockCopy(first, 0, ret, 0, first.Length);
Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
return ret;
}
}
Then to use it like:
Keys.FacebookClientId = DecryptionHelper.Decrypt(FacebookClientId);
using System;
using System.Text;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Encodings;
using System.Security.Cryptography;
using System.IO;
public static string CreateSecureLoad(string unencryptedPayload, ref byte[] generatedAesKey)
{
// This method generates and returns a secure payload ​
RijndaelManaged cryptoAlgo = new RijndaelManaged
{
Padding = PaddingMode.PKCS7,
Mode = CipherMode.ECB,
KeySize = 128,
BlockSize = 128
};​
generatedAesKey = cryptoAlgo.Key;
var clearTextArray = Encoding.UTF8.GetBytes(unencryptedPayload);
var encryptor = cryptoAlgo.CreateEncryptor();​
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(
msEncrypt,
encryptor,
CryptoStreamMode.Write))
{
csEncrypt.Write(clearTextArray);
csEncrypt.FlushFinalBlock();
var cipher = msEncrypt.ToArray();
return Convert.ToBase64String(cipher);
}
}
}
public static string CreateSecureKey(byte[] aesKey, string privateKeyPEM)
{
// This method generates and returns a secure key
// Accepts the string contents of the private key PEM file as input
​
var encryptEngine = new Pkcs1Encoding(new RsaEngine());
​
using (var textReader = new StringReader(privateKeyPEM))
{
var pemReader = new PemReader(textReader);
var keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
encryptEngine.Init(true, keyPair.Private);
}
​
var encrypted = Convert.ToBase64String(
encryptEngine.ProcessBlock(
aesKey,
0,
aesKey.Length));
return encrypted;
}
static void Main(string[] args)
{
String payload = "some json";
​
byte[] generatedAesKey = new byte[16];
var privateKeyPEM = File.ReadAllText("privatekey.pem");
​
var securePayload = CreateSecureLoad(payload, ref generatedAesKey);
var secureKey = CreateSecureKey(generatedAesKey, privateKeyPEM);
​
// Return encrypted key
Console.WriteLine("secureKey: " + secureKey);
​
// Return encrypted payload
Console.WriteLine("securePayload: " + securePayload);​
Console.ReadLine();​
}
}

Encrypt data on reactjs and decrpt it in c# app

I have to encrypt some data on reactjs side and decrypt data in c# app.
I am trying rijndael-js in reactjs. And on c# side i am using RijndaelManaged. Own each one codes like below.
reactjs codes;
import Rijndael from "rijndael-js"
class ServiceRequester{
getCrypto()
{
let original = "tolga";
let key = "00000000000000000000000000000000"; // 32 length
let iv = "0000000000000000"; // 16 length
let cipher = new Rijndael(key, "cbc");
let ciphertext = cipher.encrypt(original, 128, iv);
console.log(ciphertext.toString("base64"));
console.log(cipher.decrypt(ciphertext, 128, iv).toString());
return ciphertext.toString("base64");
}
}
c# code;
public static string Decrypt(string encryptedText)
{
if (encryptedText == null)
{
return null;
}
var bytesToBeDecrypted = Convert.FromBase64String(encryptedText);
var bytesDecrypted = Decrypt(bytesToBeDecrypted);
return Encoding.UTF8.GetString(bytesDecrypted);
}
private static byte[] Decrypt(byte[] bytesToBeDecrypted)
{
byte[] decryptedBytes = null;
using (var ms = new MemoryStream())
{
using (var AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
AES.Key = new byte[32];
AES.IV = new byte[16];
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.Close();
}
decryptedBytes = ms.ToArray();
}
}
return decryptedBytes;
}
c# app been throwing an error. Error is
System.Security.Cryptography.CryptographicException: 'Padding is invalid and cannot be removed.

Padding is invalid and cannot be removed - randomly thrown by RijndaelManaged

I have searched for a good plain text file encryption in C# and came across a post on SO and have been using it for a while now.
I don't remember the original post I got the code from; but here's the copy of the original code, slightly modified for my own use:
public static class StringCipher
{
private const int Keysize = 256;
private const int DerivationIterations = 1000;
public static string Encrypt(string plainText, string fileName)
{
try
{
var saltStringBytes = Generate256BitsOfRandomEntropy();
var ivStringBytes = Generate256BitsOfRandomEntropy();
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
using (var password = new Rfc2898DeriveBytes(Machine.Udid, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var symmetricKey = new RijndaelManaged())
{
symmetricKey.BlockSize = 256;
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
var cipherTextBytes = saltStringBytes;
cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
memoryStream.Close();
cryptoStream.Close();
return Convert.ToBase64String(cipherTextBytes);
}
}
}
}
}
}
catch (Exception exception)
{
throw new Exception("Failed to encrypt " + fileName + " - " + exception.Message, exception);
}
}
public static string Decrypt(string cipherText, string fileName)
{
try
{
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
using (var password = new Rfc2898DeriveBytes(Machine.Udid, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var symmetricKey = new RijndaelManaged())
{
symmetricKey.BlockSize = 256;
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream(cipherTextBytes))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
var plainTextBytes = new byte[cipherTextBytes.Length];
var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
}
}
}
}
}
}
catch (Exception exception)
{
throw new Exception("Failed to decrypt " + fileName + " - " + exception.Message, exception);
}
}
private static byte[] Generate256BitsOfRandomEntropy()
{
var randomBytes = new byte[32];
using (var rngCsp = new RNGCryptoServiceProvider())
{
rngCsp.GetBytes(randomBytes);
}
return randomBytes;
}
}
Every now and then, my app randomly throws this exception:
Padding is invalid and cannot be removed.
And this is my stack trace:
at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.Stream.Dispose()
at DisplayMapper.Lib.StringCipher.Decrypt(String cipherText, String fileName) in C:\Users\Latheesan\Desktop\MyApp\StringCipher.cs:line 82
The line 82 is referring to this:
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
I have been reading up on this error and many post point to saying that the same key/password used to encrypt must be used to decrypt etc...
That is what I am doing in my implementation, I use a static password generated from a hash of the cpu/motherboard/hdd serial numbers with some random strings (which comes from Machine.Udid.
So, I am not sure what's causing this error. I haven't been able to re-produce it as the error occurs randomly. Any ideas?

Categories

Resources