i have a problem, i tried to fix it myself but i cant.
My program search als .txt files from a directory. Then it read the files and encrypt each file and overwrite the old file. That works fine. Now i want to decrypt the txt files, the following happens:
Here you can see the encrypted text and the decrypted text
So the Problem is, the .txt file becomes encrypted, and the decryption works too, but when i decrypt there dont come the original text. You can see it on the picture, there are coming only wired letters. I cant understand why, i use the same salt and the same password.
Here is my code:
The first 3 snippets are for encryption, the other 3 for decryption.
foreach (var file in d2.GetFiles("*.txt"))
{
Console.WriteLine(file.FullName, file.Name);
string temppfad = file.FullName;
StreamReader sr = new StreamReader(temppfad);
string Inhalt = sr.ReadToEnd();
Console.WriteLine(Inhalt + "\n");
string Verschlüsselterinhalt = Verschlüsseln(Password, Inhalt);
sr.Close();
File.WriteAllText(temppfad, Verschlüsselterinhalt);
}
These Part is still working, just upload it to understand it better.
The encryption parts:
static string Verschlüsseln(string PW, string original)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
myRijndael.GenerateKey();
myRijndael.GenerateIV();
byte[] salt = Encoding.ASCII.GetBytes("0PQUX76U0adfaDADFexA888887Dz3J3X");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(PW, salt);
myRijndael.Key = key.GetBytes(myRijndael.KeySize / 8);
myRijndael.IV = key.GetBytes(myRijndael.BlockSize / 8);
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);
StringBuilder s = new StringBuilder();
foreach (byte item in encrypted)
{
s.Append(item.ToString("X2") + " ");
}
Console.WriteLine("Encrypted: " + s + "\n\n");
return s.ToString();
}
}
static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
byte[] encrypted;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.Zeros;
// 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 the encrypted bytes from the memory stream.
return encrypted;
}
I think to that point all is ok, now I will post the decryption parts.
foreach (var file in d2.GetFiles("*.txt"))
{
Console.WriteLine(file.FullName, file.Name);
string temppfad = file.FullName;
StreamReader sr = new StreamReader(temppfad);
string Inhalt = sr.ReadToEnd();
Console.WriteLine("Inhalt: " + Inhalt + "\n");
string Entschlüsselterinhalt = Entschlüsseln(Password, Inhalt);
sr.Close();
File.WriteAllText(temppfad, Entschlüsselterinhalt);
}
static string Entschlüsseln(string PW, string original)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
myRijndael.GenerateKey();
myRijndael.GenerateIV();
byte[] salt = Encoding.ASCII.GetBytes("0PQUX76U0adfaDADFexA888887Dz3J3X");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(PW, salt);
myRijndael.Key = key.GetBytes(myRijndael.KeySize / 8);
myRijndael.IV = key.GetBytes(myRijndael.BlockSize / 8);
// Decrypt the bytes to a string.
byte[] originalbytes = Encoding.ASCII.GetBytes(original);
string decrypted = DecryptStringFromBytes(originalbytes, myRijndael.Key, myRijndael.IV);
//Display the original data and the decrypted data.
Console.WriteLine("Decrypted: " + decrypted);
return decrypted;
}
}
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.Zeros;
// 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;
}
I would be very happy when someone could help me.
UPDATE!!!
I edited now my code, now it looks so:
foreach (var file in d2.GetFiles("*.txt"))
{
Console.WriteLine(file.FullName, file.Name);
string temppfad = file.FullName;
StreamReader sr = new StreamReader(temppfad);
string Inhalt = sr.ReadToEnd();
Console.WriteLine(Inhalt + "\n");
byte[] Verschlüsselterinhalt = Verschlüsseln(Password, Inhalt);
sr.Close();
File.WriteAllBytes(temppfad, Verschlüsselterinhalt);
}
static byte[] Verschlüsseln(string PW, string original)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
byte[] salt = Encoding.ASCII.GetBytes("0PQUX76U0adfaDADFexA888887Dz3J3X");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(PW, salt);
myRijndael.Key = key.GetBytes(myRijndael.KeySize / 8);
myRijndael.IV = key.GetBytes(myRijndael.BlockSize / 8);
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);
return encrypted;
}
}
I think that part is ok, now on decryption i get an error
foreach (var file in d2.GetFiles("*.txt"))
{
Console.WriteLine(file.FullName, file.Name);
string temppfad = file.FullName;
StreamReader sr = new StreamReader(temppfad);
string Inhalt = sr.ReadToEnd();
Console.WriteLine("Inhalt: " + Inhalt + "\n");
string Entschlüsselterinhalt = Entschlüsseln(Password, Inhalt);
sr.Close();
File.WriteAllText(temppfad, Entschlüsselterinhalt);
}
static string Entschlüsseln(string PW, string original)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
byte[] salt = Encoding.ASCII.GetBytes("0PQUX76U0adfaDADFexA888887Dz3J3X");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(PW, salt);
myRijndael.Key = key.GetBytes(myRijndael.KeySize / 8);
myRijndael.IV = key.GetBytes(myRijndael.BlockSize / 8);
// Decrypt the bytes to a string.
byte[] originalbytes = Encoding.ASCII.GetBytes(original);
string decrypted = DecryptStringFromBytes(originalbytes, myRijndael.Key, myRijndael.IV);
//Display the original data and the decrypted data.
Console.WriteLine("Decrypted: " + decrypted);
return decrypted;
}
}
The error comes here:
Errormessage
Here there full code:
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.Zeros;
// 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;
}
Greetings
The issue is you are messing with the encrypted text by doing this
StringBuilder s = new StringBuilder();
foreach (byte item in encrypted)
{
s.Append(item.ToString("X2") + " ");
}
As Damien mentioned you should return a byte array from static string Verschlüsseln(string PW, string original) and use File.WriteAllBytes to write it to file. You can then use File.ReadAllBytes to read it from the file and pass a byte[] into you're decrypt method and you don't need to do anything to do with encoding.
SOLVED
Thank you for your much help, my last error was pretty easy, just a little mistake, here the solution of the part where was the error:
foreach (var file in d2.GetFiles("*.txt"))
{
Console.WriteLine(file.FullName, file.Name);
string temppfad = file.FullName;
byte[] Inhaltsbyte = File.ReadAllBytes(temppfad);
string Entschlüsselterinhalt = Entschlüsseln(Password, Inhaltsbyte);
File.WriteAllText(temppfad, Entschlüsselterinhalt);
}
Related
I call this function EncryptStringToBytes_Aes to encrypt ID, when I convert to Base64 string, it looks like that: "Zr3EChQwtq1Wl/XLhBGSIZnHI098DKJaeujDmFfS25s="; "rGp5t04HgiKSkM10ImhOEwXZTc/eawOwlZTySRp6ZMk=", how to create string without "/" or "=", later I have to decrypt the ID.
string original = "IDNumber";
// Create a new instance of the AesCryptoServiceProvider
// class. This generates a new key and initialization
// vector (IV).
using (AesCryptoServiceProvider myAes = new AesCryptoServiceProvider())
{
Console.WriteLine("Original: {0} \n", original);
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);
Console.WriteLine("Encrypted: {0} \n", Convert.ToBase64String(encrypted));
}
static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
byte[] encrypted;
// Create an AesCryptoServiceProvider object
// with the specified key and IV.
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// 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;
}
static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an AesCryptoServiceProvider object
// with the specified key and IV.
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// 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;
}
Thank you "Progman", you are smart, fixed my problem.
Now use class Base64UrlEncoder from namespace Microsoft.IdentityModel.Tokens
const string StringToEncode = "Zr3EChQwtq1Wl/XLhBGSIZnHI098DKJaeujDmFfS25s=";
var encodedStr = Base64UrlEncoder.Encode(StringToEncode);
var decodedStr = Base64UrlEncoder.Decode(encodedStr);
I am Learning C#, and are practicing with decryption and encryption.
I used the Aes Class Example from MSDN, and the encryption is working great.
However, when i am trying to decrypt the textfile, nothing happens.
I figured i had done something wrong in the decryption function, so i tested with a string instead.
The decryption worked perfect with the string So i am wondering what i am doing wrong.
This is what my encryption and decryption looks like:
//The encryption
string path = #"C:\encrypt.txt";
//The path where my .txt file is.
string textfile = File.ReadAllText(path);
//Reading the text in the file and storing it in a string.
byte[] ByteToEncrypt = EncryptStringToBytes(textfile, myAes.Key, myAes.IV);
//From The Aes class example
string encrypted = "";
//Creating a string to store the bytes in.
for (int i = 0; i < ByteToEncrypt.Length; i++)
{
encrypted = encrypted + ByteToEncrypt[i];
//Adding all the bytes from an array to string.
}
File.WriteAllText(path, encrypted, LATIN1);
//Writing the encrypted string to the .txtfile.
//The decryption
string decrypted = DecryptStringFromBytes(ByteToEncrypt, myAes.Key, myAes.IV);
//From the Aes class example.
File.WriteAllText(path, Decrypted, LATIN1);
//Writing the decrypted string to textfile.
I am posting the Aes class below for further information.
static byte[] EncryptStringToBytes(string plaintext, byte[] Key, byte[] IV)
{
//Checking the arguments
if (string.IsNullOrEmpty(plaintext))
{
throw new ArgumentNullException("plaintext");
}
else if (Key == null || Key.Length <= 0)
{
throw new ArgumentNullException("key");
}
else if (IV == null || IV.Length <= 0)
{
throw new ArgumentNullException("IV");
}
byte[] encrypted;
//Create an Aes object
//With the specified key and IV
using (Aes Aesalg = Aes.Create())
{
Aesalg.Key = Key;
Aesalg.IV = IV;
//Create a encryptor 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))
{
swEncrypt.Write(plaintext);
}
encrypted = msencrypt.ToArray();
}
}
}
return encrypted;
}
static string DecryptStringFromBytes(byte[] ciphertext, byte[] Key, byte[] IV)
{
if (ciphertext == null || ciphertext.Length <= 0)
{
throw new ArgumentNullException("plaintext");
}
else if (Key == null || Key.Length <= 0)
{
throw new ArgumentNullException("Key");
}
else if (IV == null || IV.Length <= 0)
{
throw new ArgumentNullException("IV");
}
string plaintext = null;
using (Aes Aesalg = Aes.Create())
{
Aesalg.Key = Key;
Aesalg.IV = IV;
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))
{
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
You cannot just add bytes to a String. Byte can have any value between 00 and FF inclusive (using hexadecimal representation). You simply seem to add those bytes as integers to the string, as
encrypted = encrypted + ByteToEncrypt[i];
simply creates a String value such as "0255" for byte values 00 and FF. Of course, you will have an issue when you try and decrypt such a string, if only because the bytes are not separated anymore.
Instead, you should create a base 64 encoding of the ciphertext after encryption, and convert it back into bytes before decrypting. Or, as ntoskrnl suggests, you can of course just treat the ciphertext as binary all the way, if that's an option.
I am trying to read the binary contents of a file with File.ReadAllBytes and getting the exception that access to the file is denied. Do I have to open the file first? Its taking the exception path in this try-catch and displaying.
Unable to load configuration data. Access to the path 'c:\worl\Project Alpha\Code\AlphaBackendService\AlphaBackendService\bin\Debug\alphaService.xml' is denied.
What am I missing?
try
{
string path = AppDomain.CurrentDomain.BaseDirectory;
eventLog1.WriteEntry(path);
string fileName = System.IO.Path.Combine(path, "alphaService.xml");
string sKey = "LvtZELDrB394hbSOi3SurLWAvC8adNpZiJmQDJHdfJU=";
Byte[] keyBytes = Convert.FromBase64String(sKey);
Byte[] contentsBytes = File.ReadAllBytes(fileName);
string xmlStr = Encoding.UTF8.GetString(contentsBytes);
DecryptStringFromBase64String(xmlStr, keyBytes);
eventLog1.WriteEntry(xmlStr);
using (XmlReader reader = XmlReader.Create(new StringReader(xmlStr)))
{
reader.ReadToFollowing("DatabaseServerName");
DatabaseServerName = reader.ReadElementContentAsString();
reader.ReadToFollowing("DatabaseUserName");
DatabaseUserName = reader.ReadElementContentAsString();
reader.ReadToFollowing("DatabasePassword");
DatabasePassword = reader.ReadElementContentAsString();
reader.ReadToFollowing("RegistrationCode");
RegistrationCode = reader.ReadElementContentAsString();
}
eventLog1.WriteEntry("Configuration data loaded successfully");
}
catch (Exception ex)
{
eventLog1.WriteEntry("Unable to load configuration data. " + ex.Message);
}
The Decrypt function requires a string with the contents but it does a Convert.FromBase84String so I don't know if File.ReadAllBytes should be used.
static string DecryptStringFromBase64String(string cipherText, byte[] Key)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
string plaintext = null;
// this is all of the bytes
var allBytes = Convert.FromBase64String(cipherText);
// get our IV that we pre-pended to the data
byte[] iv = new byte[KeySize / 16];
Array.Copy(allBytes, iv, iv.Length);
// get the data we need to decrypt
byte[] cipherBytes = new byte[allBytes.Length - iv.Length];
Array.Copy(allBytes, iv.Length, cipherBytes, 0, cipherBytes.Length);
using (var aes = Aes.Create())
{
// Create a decrytor to perform the stream transform.
var decryptor = aes.CreateDecryptor(Key, iv);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherBytes))
{
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 use the function EncryptStringToBytes to encrypt plain text to array of bytes and
finally convert array of bytes to string and return it then.
I use another function to Decrypt Encrypted text to plaint text.
I try to scramble a text with RC2 but it raises this error:
Rijndael class to encrypt and then decrypt data
Here's the code:
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
namespace RC2CryptoServiceProvider_Examples
{
class MyMainClass
{
static string EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
byte[] encrypted;
// Create an Rijndael object
// with the specified key and IV.
using (Rijndael rijAlg = Rijndael.Create())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// 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 the encrypted bytes from the memory stream.
return System.Text.Encoding.UTF8.GetString(encrypted);**
}
static string DecryptStringFromBytes(string Codedtext, byte[] Key, byte[] IV)
{
byte[] cipherText = System.Text.Encoding.UTF8.GetBytes(Codedtext);
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Rijndael object
// with the specified key and IV.
using (Rijndael rijAlg = Rijndael.Create())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// 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;
}
public static void Main()
{
try
{
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
string original = "Here is some data to encrypt!";
// Create a new instance of the Rijndael
// class. This generates a new key and initialization
// vector (IV).
using (Rijndael myRijndael = Rijndael.Create())
{
// Encrypt the string to an array of bytes.
string encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);
// Decrypt the bytes to a string.
string roundtrip = DecryptStringFromBytes(encrypted, myRijndael.Key, myRijndael.IV);
//Display the original data and the decrypted data.
Console.WriteLine("Original: {0}", original);
Console.WriteLine("Round Trip: {0}", roundtrip);
}
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}
Console.ReadLine();
}
}
}
This is the problem (or at least a problem):
return System.Text.Encoding.UTF8.GetString(encrypted);
The encrypted data isn't UTF-8 text. It's arbitrary binary data. Don't treat it as if it were encoded text.
If you really need to pass arbitrary binary data around as a string, use Base64:
return Convert.ToBase64String(encrypted);
Then in DecryptStringFromBytes, you'd use:
byte[] cipherText = Convert.FromBase64String(codedText);
(Parameter name changed to comply with conventions.)
I'm working on a program that sends and receives messages just like messengers, and I need to encrypt the message on send button and decrypt the message when received. I'm using the RijndaelManaged class and the following methods to encrypt/decrypt
public byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
byte[] encrypted;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// 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 the encrypted bytes from the memory stream.
return encrypted;
}
And
public string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// 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;
}
Here's how I invoke the previous methods:
private void SendMessage()
{
string str;
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
str = enc.GetString(this.EncryptStringToBytes(this.txtNewMessage.Text, myRijndael.Key, myRijndael.IV ));
if ( this.remoteClient.Connected && this.txtNewMessage.Text.Trim() != "")
{
this.remoteClient.SendCommand(new Proshot.CommandClient.Command(Proshot.CommandClient.CommandType.Message, this.targetIP,str));
this.txtMessages.Text += this.remoteClient.NetworkName + ": " + this.txtNewMessage.Text.Trim() + "//---SENT" + Environment.NewLine;
this.txtNewMessage.Text = "";
this.txtNewMessage.Focus();
}
}
private void private_CommandReceived(object sender , CommandEventArgs e)
{
string str;
byte[] byteString;
str = e.Command.MetaData;
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byteString = encoding.GetBytes(str);
switch ( e.Command.CommandType )
{
case ( CommandType.Message ):
if ( !e.Command.Target.Equals(IPAddress.Broadcast) && e.Command.SenderIP.Equals(this.targetIP))
{
//myRijndael.Padding = PaddingMode.Zeros;
this.txtMessages.Text += e.Command.SenderName + ": " + this.DecryptStringFromBytes(byteString, myRijndael.Key, myRijndael.IV) + "//---Received" + Environment.NewLine;
if ( !this.activated)
{
if(this.WindowState == FormWindowState.Normal || this.WindowState == FormWindowState.Maximized)
ShareUtils.PlaySound(ShareUtils.SoundType.NewMessageReceived);
else
ShareUtils.PlaySound(ShareUtils.SoundType.NewMessageWithPow);
this.Flash(this.Handle , FlashMode.FLASHW_ALL , 3);
}
}
break;
}
}
The problem is I'm getting exception when decrypting Cryptographic Exception - Length of the data to decrypt is invalid, I can't figure out why ?
Probably you should flush your CryptoStream while encrypting before you set the encrypted byte array:
...
csEncrypt.FlushFinalBlock();
encrypted = msEncrypt.ToArray();
...
An extract from CryptoStream.FlushFinalBlock Method:
Calling the Close method will call FlushFinalBlock. If you do not call
Close, call FlushFinalBlock to complete flushing the buffer. Call
FlushFinalBlock only when all stream activity is complete.
Obviously, if you call Close, all data will be lost, as it will close the underlying MemoryStream as well.