I am doing an Aes decryption but I am keep getting an exception "Padding is invalid and cannot be removed". The encrypted message given to me as response from the server which I am trying to decrypt. This is the function I am using to decrypt the code
Any ideas?
public async static Task<string> DecriptResponse(string data)
{
try
{
byte[] decodedData = Convert.FromBase64String(data);
using (Aes aesAlg = new AesManaged())
{
aesAlg.Key = Encoding.UTF8.GetBytes(Constants.DecryptionKey);
aesAlg.IV = Encoding.UTF8.GetBytes(Constants.DecryptionIv);
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(decodedData))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
string plaintext = srDecrypt.ReadToEnd();
Debug.WriteLine(plaintext);
return plaintext;
}
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
return "";
}
return "";
}
Related
We have implemented AES encryption in our project. And it works fine.
But, if the user tampers the byte[] then the Decrypt function returns a wrong plain text with different symbols like � in it.
We want to handle this case by determining that the data is tampered.
Please find below the code of Decrypt function:
public static string Decrypt(string encryptedText)
{
try
{
// First convert the base64 string to byte[].
var cipherText = Convert.FromBase64String(encryptedText);
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
string plaintext = null;
// Create an Aes object
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Encoding.ASCII.GetBytes("abc");
aesAlg.IV = Encoding.ASCII.GetBytes("xyz");
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
catch (Exception ex)
{
return null;
}
}
Please help me to solve my issue.
Thanks!
I have problem with reading from encrypted files. have 2 sources of files, one is Rapsberry PI (Java), the second is desktop appliaction (.Net 4.6.1).
When I'm creating a encrypted file on my device and then want to read it in my desktop app, there is no problem with decrypting and encoding to string.
In the same app I create the same file, adding next element to list in the file on each 5s. When I read the file in my app, I got Unexpected end when reading json. path error.
I have checked models and they are both the same and valid.
For encryption/decryption I'm using AES algorithm.
There is my code from my desktop app:
Writing data:
Aes myAes = Aes.Create();
myAes.Key = Encoding.ASCII.GetBytes("abcde");
byte[] roundtrip = EncryptStringToBytes_Aes(output, myAes.Key, myAes.IV);
DirectoryInfo info = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
string pathSave =info + "\\test.plkx";
using (FileStream sourceStream = new FileStream (pathSave , FileMode.Append))
{
sourceStream.Write(roundtrip, 0, roundtrip.Length);
};
The method byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.Mode = CipherMode.ECB;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
There is my reader:
byte[] data = null;
data = new byte[fileStream.Length];
fileStream.Position = 0;
fileStream.Read(data, 0, (int)fileStream.Length);
Aes myAes = Aes.Create();
myAes.Key = Encoding.ASCII.GetBytes("abcde");
byte[] roundtrip = DecryptStringFromBytes_Aes(data, myAes.Key, myAes.IV);
return new MemoryStream(roundtrip);
And byte[] DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV) method:
byte[] plaintext = null;
using (Aes aesAlg = Aes.Create())
{
aesAlg.Mode = CipherMode.ECB;
aesAlg.Key = Key;
aesAlg.IV = IV;
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msDecrypt = new MemoryStream())
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
{
csDecrypt.Write(cipherText, 0, cipherText.Length);
}
plaintext = msDecrypt.ToArray();
var ads = ASCIIEncoding.ASCII.GetString(plaintext);
//There I got exception
var ab = DeserializeStream(new MemoryStream(plaintext));
}
}
return plaintext;
DeserializeStream method:
public RecorderValueTest DeserializeStream(MemoryStream stream)
{
RecorderValueTest r = new RecorderValueTest();
using (BsonDataReader reader = new BsonDataReader(stream))
{
JsonSerializer serializer = new JsonSerializer();
r = serializer.Deserialize<RecorderValueTest>(reader);
}
return r;
}
edit
I have tried this:
xxx = new xxx
{
data = listRecord,
};
string output = JsonConvert.SerializeObject(plkx);
try
{
using (BsonDataReader reader = new BsonDataReader(new MemoryStream(Encoding.UTF8.GetBytes(output))))
{
JsonSerializer serializer = new JsonSerializer();
var r = serializer.Deserialize<xxx>(reader);
}
} catch (Exception exc)
{ }
and still get the same error while deserialization. JsonConvert.DeserializeObject<xxx>(plkx); also didn't work.
Hello Friendly OverFlowers:
I have a line of code in the bigger example that is not working:
plaintext = srDecrypt.ReadToEnd();
It reports an exception:
The input data is not a complete block.
I have:
1) Looked at Encodings
2) Verified Decrypt (args) were correct.
Oh the intention from the simple main was to get back the encrypted value from the decrypted value. The plaintext = line is in the Decryption portion.
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace Encryptor
{
class Program
{
static void Main(string[] args)
{
CryptDecrypt cd = new CryptDecrypt(new Guid());
string s = cd.Encrypt("Password");
Console.WriteLine(s);
string t = cd.Decrypt(s);
Console.WriteLine(t);
Console.ReadKey();
}
}
public class CryptDecrypt
{
private byte[] Key;
private byte[] IV;
public CryptDecrypt(Guid keyBase)
{
string Hash = keyBase.ToString();
Key = Encoding.UTF8.GetBytes(Hash.Take(32).ToArray());
IV = Encoding.UTF8.GetBytes(Hash.Reverse().Take(16).ToArray());
}
public string Encrypt(string plainText)
{
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.IV = IV;
aesAlg.Key = IV;
aesAlg.Padding = PaddingMode.Zeros;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return Convert.ToBase64String(encrypted);
}
public string Decrypt(string inputStr)
{
// Check arguments.
if (inputStr == null || inputStr.Length <= 0)
throw new ArgumentNullException("cipherText");
byte[] cipherText = Encoding.UTF8.GetBytes(inputStr);
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.Padding = PaddingMode.Zeros;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
}
}
You have two errors. First is that you use IV as the Key in the Encrypt method, and second you forgot to convert back from Base64 before decrypting.
See the code amended to correct these problems.
void Main()
{
CryptDecrypt cd = new CryptDecrypt(new Guid());
string s = cd.Encrypt("Password");
Console.WriteLine(s);
string t = cd.Decrypt(s);
Console.WriteLine(t);
}
public class CryptDecrypt
{
private byte[] Key;
private byte[] IV;
public CryptDecrypt(Guid keyBase)
{
string Hash = keyBase.ToString();
Key = Encoding.UTF8.GetBytes(Hash.Take(32).ToArray());
IV = Encoding.UTF8.GetBytes(Hash.Reverse().Take(16).ToArray());
}
public string Encrypt(string plainText)
{
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.IV = IV;
aesAlg.Key = Key; <- HERE
aesAlg.Padding = PaddingMode.Zeros;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
swEncrypt.Flush();
}
encrypted = msEncrypt.ToArray();
}
}
}
return Convert.ToBase64String(encrypted);
}
public string Decrypt(string inputStr)
{
// Check arguments.
if (inputStr == null || inputStr.Length <= 0)
throw new ArgumentNullException("cipherText");
byte[] cipherText = Convert.FromBase64String(inputStr); <- HERE
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.Padding = PaddingMode.Zeros;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
}
the other links are not being useful to me.
i am encrypting string before saving in mysql database.that is working fine.but when i want to retrieve, its giving me length of data to encrypt is invalid error.
before my encryption requirement, i was using datatype of varchar size 500.now im using varbinary of size 800.can any1 advise me on the size too?
encryption method:
public static byte[] encryptStringToBytes(string plainText)
{
byte[] encrypted;
//create an Rijndael object
using (Rijndael rijAlg = Rijndael.Create())
{
//create a decrytor to perform the stream transform.
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
//create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return encrypted;
}
decryption method:
public static string decryptStringFromBytes(byte[] cipherText)
{
string plaintext = null;
//create an Rijndael object
using (Rijndael rijAlg = Rijndael.Create())
{
//create a decrytor to perform the stream transform.
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
//create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
//read the decrypted bytes from the decrypting stream and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
retrieving from resultset
using (Rijndael myRijndael = Rijndael.Create())
{
temp5 = EncryptDecrypt.decryptStringFromBytes((byte[])reader.GetValue(reader.GetOrdinal("Body")));
}
You are not controlling key and IV in any way. This is kind of a problem... :) It results in your encryption being a random scrambling of the data because key and IV are randomly initialized by the framework.
Use the same key and IV for decryption as you are using them for encryption. Why do you think the database has to do with the problem? It hasn't and there is not evidence for that.
Please suggest me where i need to update/refactor the code to get rid of exception. I am getting exception while I try to decrypt the encrypted string using following code.
Following line is throwing exception
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
public string EncryptAuthenticationTokenAes(string plainText)
{
byte[] encrypted;
// Create an AesManaged object
// with the specified key and IV.
using (AesManaged aesAlg = new AesManaged())
{
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
aesAlg.Padding = PaddingMode.None;
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return Convert.ToBase64String(encrypted);
}
public string DecryptPasswordAes(string encryptedString)
{
//Convert cipher text back to byte array
byte[] cipherText = Convert.FromBase64String(encryptedString);
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an AesManaged object
// with the specified key and IV.
using (AesManaged aesAlg = new AesManaged())
{
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
aesAlg.Padding = PaddingMode.None;
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
Pretty standard bug when using CryptoStream, you forgot to force it to encrypt the last bytes of the stream. It keeps bytes in an internal buffer until enough of them arrive to emit a block. You must force the last few bytes out. Fix:
using (var msEncrypt = new MemoryStream())
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt)) {
swEncrypt.Write(plainText);
csEncrypt.FlushFinalBlock();
encrypted = msEncrypt.ToArray();
}
You got the exception when decrypting it because encrypted is missing the final padding. The real problem is caused by the using statement, you wouldn't have this problem if you waited obtaining the encrypted bytes until after the CryptoStream is closed. But that doesn't work well because the using statement on the StreamWriter also closes the CryptoStream and the MemoryStream. Explicitly using FlushFinalBlock() is the best workaround.