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.
Related
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;
}
}
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 "";
}
I've been trying to understand encryption/decryption code of TripleDES for some days. And I have seen many codes in the google, and the code shown below is one of them.
static void Main(string[] args)
{
string original = "Here is some data to encrypt!";
TripleDESCryptoServiceProvider myTripleDES = new TripleDESCryptoServiceProvider();
byte[] encrypted = EncryptStringToBytes(original, myTripleDES.Key, myTripleDES.IV);
string encrypt = Convert.ToBase64String(encrypted);
string roundtrip = DecryptStringFromBytes(encrypted, myTripleDES.Key, myTripleDES.IV);
Console.WriteLine("encryted: {0}", encrypt);
Console.WriteLine("Round Trip: {0}", roundtrip);
Console.ReadLine();
}
static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
byte[] encrypted;
using (TripleDESCryptoServiceProvider tdsAlg = new TripleDESCryptoServiceProvider())
{
tdsAlg.Key = Key;
tdsAlg.IV = IV;
ICryptoTransform encryptor = tdsAlg.CreateEncryptor(tdsAlg.Key, tdsAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return encrypted;
}
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
string plaintext = null;
using (TripleDESCryptoServiceProvider tdsAlg = new TripleDESCryptoServiceProvider())
{
tdsAlg.Key = Key;
tdsAlg.IV = IV;
ICryptoTransform decryptor = tdsAlg.CreateDecryptor(tdsAlg.Key, tdsAlg.IV);
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
There is no error in the code. I works fine. But strangely I noticed that the plainText is never been encoded. There is no line like Encoding.Unicode.GetBytes(plainText); or Encoding.UTF8.GetBytes(plainText); or similar like that. So, my question is , how does (in the code) the plainText which is a string gets converted to the encrypted byte? Is there any work done inside the streams? If thats so then where and how? As far as I understood there is no such line in between the streams that converts the string to byte. So , How does the overall code is working without this basic transformation?
Update:
Is this code really a valid code?
You are sending the plaintext to the encryption stream in the line swEncrypt.Write(plaintext). This does the byte conversion.
The StreamWriter is doing the encoding. The constructor being used specifies UTF-8 encoding:
This constructor creates a StreamWriter with UTF-8 encoding without a
Byte-Order Mark (BOM)
I am having some issues using RFC2898DeriveBytes. Here is the situation: I am creating a public/private key pair using RSACryptoProvider and I use Rfc2898 to encrypt the private key file. I am using the following code for encryption:
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(frm2.txtPassphrase.Text, saltbyte);
// Encrypt the data.
TripleDES encAlg = TripleDES.Create();
encAlg.Key = key.GetBytes(16);
// Create the streams used for encryption.
byte[] encrypted;
using (FileStream fsEncrypt = new FileStream(#"D:\test.xml", FileMode.Create, System.IO.FileAccess.Write))
{
using (CryptoStream csEncrypt = new CryptoStream(fsEncrypt, encAlg.CreateEncryptor(), CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(privateKeyXml);
}
}
}
This is for decryption:
TripleDES decAlg = TripleDES.Create();
Rfc2898DeriveBytes key1 = new Rfc2898DeriveBytes(frm1.txtPassphrase.Text, saltbyte);
decAlg.Key = key1.GetBytes(16);
// Create the streams used for decryption.
using (FileStream fsDecrypt = new FileStream(#"D:\test.xml", FileMode.Open, System.IO.FileAccess.Read))
{
using (CryptoStream csDecrypt = new CryptoStream(fsDecrypt, decAlg.CreateDecryptor(), CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
decPrivateKeyXml = srDecrypt.ReadToEnd();
}
}
}
Now the problem is that when I get the decPrivateKeyXml, all except the first few words come out correct. The first few words are just scrambled:
"�� ���dalue><Modulus>u9N+amIgXTw1zzJ+bxXoKaaGwCVFeXkKvdx0vhd24X7vvcJpnkA6gFgOeypbTTGm3if1QM/lyLN3qoprBkHJKDo7ldzj5a4L2Xb1tP1yUyNDban/KzkzsGK0h3fLO8UxRE6cHIB5cyEUmgmkjpFoXzz7DovUrZh3Z3qV20AHZLs=</Modulus><Exponent>AQAB</Exponent><P>5pCr4yPtn8ZyZskIpFM9pgZI1BUBIJYYhnYPywrMTj1smsQGuCswXNrcKsGvF6c9KrrXFF69AgbzcAsQwI449Q==</P><Q>0IvXoP8uELT/v8lG5R0YmvrgTfVQNJp8n8PT7J1dN3dsCDUHa+rK2Q4XSehFHT8XQgiENICkYg6xsdJqXXxY7w==</Q><DP>KwpSrAIm966J6JoanOJVHcsKiVyqazTZuzAK3rJTVT+uKG3zeynEy3CnrOufDeFQT8u1Hr5YtioqA35tUCS8iQ==</DP><DQ>UXZOxJTpaZ1KSaBWESlMcz2MYOdybRnrlHzqS4Ms5n2/tXUBcSZGFoNqlXQli0cZzrGE8v1NOQCEaPHImrv4AQ==</DQ><InverseQ>rX3TlQMreZvjm+fNS5UK90tj/KQQAlP0u5xxgEAUVfr8ZE/hsSOcB0MuXPyeGExRyRiBdSUsj64BHOVPH9+mcw==</InverseQ><D>H04JtNtz/3YolccZsZQaJM7/iIjtwmg9NRXIU2J/yueoN51ukxSra3bBux99JimPYVmRk+LSrpfS6xa07c8LIqMaC6nFQCVF6yJH3sHuDuL7Hob2dVZ+egyjeCVu8vyn1R4/SAZ4AaWtmc8c0Zt3hSvdDMCtN61HWegFmugvRkk=</D></RSAKeyValue>"
I don't know what is wrong with the code....
.NET uses a random IV for CBC encryption. You need to store this IV with the ciphertext and initialize your decryptor with it. Normally the IV is prefixed to the ciphertext.
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.