ReadToEnd missing character c# - c#

I have an XML file with information about my stringConnection parameters which decrypted with this method:
public void DecryptFile(string sInputFileName, string sOutputFileName, string sKey)
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
FileStream fsread = new FileStream(sInputFileName, FileMode.Open, FileAccess.Read);
ICryptoTransform desdecrypt = DES.CreateDecryptor();
CryptoStream cryptostreamDecr = new CryptoStream(fsread, desdecrypt, CryptoStreamMode.Read);
//Print result
StreamWriter fsDecrypted = new StreamWriter(sOutputFileName);
//In this point ReadToEnd return the final xml result decrypted
fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
fsread.Close();
fsread.Dispose();
}
The result would be this:
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<TU>
<BD>DataBaseName</BD>
<SR>ServerName</SR>
<USR>UserDB</USR>
<CONT>Pass</CONT>
<EMP>codCompany</EMP>
<EMPDES>companyName</EMPDES>
<SUC>codLocal</SUC>
</TU>
</NewDataSet>
But ReadToEnd doesn't return the last label of my XML file, like this:
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<TU>
<BD>DataBaseName</BD>
<SR>ServerName</SR>
<USR>UserDB</USR>
<CONT>Pass</CONT>
<EMP>codCompany</EMP>
<EMPDES>companyName</EMPDES>
<SUC>codLocal</SUC>
</TU>
</NewDataSet
What's wrong with my method?

The main issue is that you are not really reading the CryptoStream to the end, because of the way it blocks data (as pointed out in this answer). Here is an approach adapted from this answer which uses a buffer to read 1024 bytes at a time.
public void DecryptFile(string sInputFileName, string sOutputFileName, string sKey)
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransform desdecrypt = DES.CreateDecryptor();
using (FileStream fsread = new FileStream(sInputFileName, FileMode.Open, FileAccess.Read))
using (StreamWriter fsDecrypted = new StreamWriter(sOutputFileName))
using (CryptoStream cryptostreamDecr = new CryptoStream(fsread, desdecrypt, CryptoStreamMode.Read))
{
//Print result
var buffer = new byte[1024];
var read = cryptostreamDecr.Read(buffer, 0, buffer.Length);
while (read > 0)
{
fsDecrypted.Write(buffer, 0, read);
read = cryptostreamDecr.Read(buffer, 0, buffer.Length);
}
}
}
You are also missing using statements, which ensure your streams are disposed correctly whether or not your program has an exception.

Related

Exception thrown: 'System.Security.Cryptography.CryptographicException' in mscorlib.dll Additional information: Bad Data

I M using code to decrypt my file. But when i am writing back to output file it is showing error : BAD DATA
Below is my code provide , line is mentioned where error is coming.
public static void DecryptFile(string sInputFilename, string sOutputFilename, string sKey)
{
try
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
//A 64 bit key and IV is required for this provider.
//Set secret key For DES algorithm.
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
//Set initialization vector.
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
//Create a DES decryptor from the DES instance.
ICryptoTransform desdecrypt = DES.CreateDecryptor();
//Create a file stream to read the encrypted file back.
using (FileStream fsread = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read))
{
//Create crypto stream set to read and do a
//DES decryption transform on incoming bytes.
using (CryptoStream cryptostreamDecr = new CryptoStream(fsread, desdecrypt, CryptoStreamMode.Read))
{
fsread.Flush();
//Print the contents of the decrypted file.
StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
////----ERROR IN THIS LINE----////
fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
}
}
}
catch(XamlParseException XEx)
{
//throw XEx;
System.Windows.MessageBox.Show(XEx.Message.ToString());
}
}
ENCRYPTION CODE
USING SAME GETBYTE IN ENCYPTION ALSO
public static void EncryptFile(string sInputFilename,string sOutputFilename,string sKey)
{
FileStream fsInput = new FileStream(sInputFilename,FileMode.Open,FileAccess.Read);
FileStream fsEncrypted = new FileStream(sOutputFilename,FileMode.Create,FileAccess.Write);
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransform desencrypt = DES.CreateEncryptor();
CryptoStream cryptostream = new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write);
byte[] bytearrayinput = new byte[fsInput.Length - 1];
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
}
The most likely reason is that you're initializing DES.IV with sKey bytes. You should use the same initialization vector here that you used dyring encryption.

Open encrypted image as Bitmap C#

I need to perform data hiding in encrypted image. To perform data hiding i need to have bitmap Image. But i don't know how to save the image as bitmap.
Below is my encryption code.
public void EncryptFile(string source, string destination)
{
string sKey = "super545";
FileStream fsInput = new FileStream(source, FileMode.Open, FileAccess.Read);
FileStream fsEncrypted = new FileStream(destination, FileMode.Create, FileAccess.Write);
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransform desencrypt = DES.CreateEncryptor();
CryptoStream cryptostream = new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write);
byte[] bytearrayinput = new byte[fsInput.Length - 1];
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Close();
fsInput.Close();
fsEncrypted.Close();
}
This is called like:
EncryptFile(originalimage, output);
output is a string variable with the path to store the encrypted image.
How can I call the function to run the encryption?
I receive the error the parameter is invalid when i hit this line:
Bitmap bitmap3 = new Bitmap(output);
I guess what you are trying to do is pretty close to this:
public void EncryptFile(string source, string destination)
{
string sKey = "super545";
FileStream fsInput = new FileStream(source, FileMode.Open, FileAccess.Read);
FileStream fsEncrypted = new FileStream(destination, FileMode.Create, FileAccess.Write);
//Consider to use something else, DES is dead
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
//use some key derivation function like pbkdf2 instead
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
//should be random, may be fixed ONLY for testing purposes
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransform desencrypt = DES.CreateEncryptor();
CryptoStream cryptostream = new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write);
//byte[] bytearrayinput = new byte[fsInput.Length - 1]; // what do you need that big buffer for anyways?
//fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
//cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
byte[] headerBuffer = new byte[54]; // buffer for our bmp header ... without any color tables or masks
//No need for lots of checks in a proof of concept
fsInput.Read(headerBuffer, 0, headerBuffer.Length);
var biCompression = BitConverter.ToInt32(headerBuffer, 30); //get biComp from header
if (biCompression != 0 && biCompression != 3)
{
throw new Exception("Compression is not in the correct format");
}
//The buffer is copied without any encryption
fsEncrypted.Write(headerBuffer, 0, headerBuffer.Length);
//copy the rest and encrypt it ... don't care about color tables and masks for now
//and let's just hope plaintext and ciphertext have the right size
fsInput.CopyTo(cryptostream);
cryptostream.Close();
fsInput.Close();
fsEncrypted.Close();
}

How can I create the program that encrypts file with 2DES (doubleDES)?

I know doubleDES is not used sine of Meet-in-the-middle Attack but i need to create a program that does that kind of encryption. I tried this but i think im stuck and just cannot figure out what am i missing..
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Mode = CipherMode.ECB;
DES.Padding = PaddingMode.Zeros;
// *****ENKRIPTIMI*****
DES.Key = utf8.GetBytes(textBox1.Text.Substring(0, 8));
StreamReader sr = new StreamReader(textBox2.Text);
string permbajtja = sr.ReadToEnd();
sr.Close();
FileStream fs1 = new FileStream(textBox2.Text, FileMode.Create, FileAccess.Write);
CryptoStream cs = new CryptoStream(fs1, DES.CreateEncryptor(), CryptoStreamMode.Write);
StreamWriter sw = new StreamWriter(cs);
sw.Write(permbajtja); sw.Flush();
sw.Close();
StreamReader stream = new StreamReader(textBox2.Text);
string msg = stream.ReadToEnd();
stream.Close();
MessageBox.Show(msg);
//*****DEKRIPTIMI*****
DES.Key = utf8.GetBytes(textBox1.Text.Substring(8, 8));
FileStream fs2 = new FileStream(textBox2.Text, FileMode.Open, FileAccess.Read);
CryptoStream cs1 = new CryptoStream(fs2, DES.CreateDecryptor(), CryptoStreamMode.Read);
StreamReader sr1 = new StreamReader(cs1);
string permbajtja1 = sr1.ReadToEnd();
// MessageBox.Show(permbajtja1);
sr1.Close();
fs2.Dispose();
fs2.Close();
StreamWriter sw1 = new StreamWriter(textBox2.Text);
sw1.Write(permbajtja1);
sw1.Flush();
sw1.Close();
**** THE PART ABOVE IS JUST FOR ENCRYPTING *****
The decryption part
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Mode = CipherMode.ECB;
DES.Padding = PaddingMode.Zeros;
// *****ENKRIPTIMI*****
DES.Key = utf8.GetBytes(textBox1.Text.Substring(8,8));
StreamReader sr = new StreamReader(textBox2.Text);
string permbajtja = sr.ReadToEnd();
sr.Close();
FileStream fs1 = new FileStream(textBox2.Text, FileMode.Create, FileAccess.Write);
CryptoStream cs = new CryptoStream(fs1, DES.CreateEncryptor(), CryptoStreamMode.Write);
StreamWriter sw = new StreamWriter(cs);
sw.Write(permbajtja); sw.Flush();
sw.Close();
StreamReader lexo = new StreamReader(textBox2.Text);
MessageBox.Show(lexo.ReadToEnd());
lexo.Close();
////*****DEKRIPTIMI*****
DES.Key = utf8.GetBytes(textBox1.Text.Substring(0, 8));
FileStream fs2 = new FileStream(textBox2.Text, FileMode.Open, FileAccess.Read);
CryptoStream cs1 = new CryptoStream(fs2, DES.CreateDecryptor(), CryptoStreamMode.Read);
StreamReader sr1 = new StreamReader(cs1);
string permbajtja1 = sr1.ReadToEnd();
MessageBox.Show(permbajtja1);
sr1.Close();
fs2.Dispose();
fs2.Close();
StreamWriter sw1 = new StreamWriter(textBox2.Text);
sw1.Write(permbajtja1);
sw1.Flush();
sw1.Close();
First of all you should write the encrypt and the decrypt method:
public static string Encrypt(string originalString, byte[] key)
{
DESCryptoServiceProvider cryptoServiceProvider = new DESCryptoServiceProvider();
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream,
cryptoServiceProvider.CreateEncryptor(key, key),
CryptoStreamMode.Write);
using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(originalString);
streamWriter.Flush();
cryptoStream.FlushFinalBlock();
streamWriter.Flush();
return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
}
}
public static string Decrypt(string cryptedString, byte[] key)
{
DESCryptoServiceProvider cryptoServiceProvider = new DESCryptoServiceProvider();
MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(cryptedString));
CryptoStream cryptoStream = new CryptoStream(memoryStream,
cryptoServiceProvider.CreateDecryptor(key, key),
CryptoStreamMode.Read);
using (StreamReader streamReader = new StreamReader(cryptoStream))
{
return streamReader.ReadToEnd();
}
}
Now you can apply twice the encryption method (and of course twice the decryption one) to your string:
byte[] key1 = ASCIIEncoding.ASCII.GetBytes("12345678");
byte[] key2 = ASCIIEncoding.ASCII.GetBytes("abcdefgh");
string originalString = "A secret string";
string cryptedString = Encrypt(Encrypt(originalString, key1), key2);
Console.WriteLine("Encrypt message: {0}", cryptedString);
Console.WriteLine("Decrypt message: {0}", Decrypt(Decrypt(cryptedString, key2), key1));
Take a look to my code, it may help you.

C# DES File Decryption Breaking Non-Text Files

I have these two methods which are pretty much copy+pastes from http://support.microsoft.com/kb/307010.
When I decrypt the files, if they are any type of text file such as .txt, .xml, .html, etc. I can open them up and everything is fine. Any type of file not just text, such as .exe, .jpg, .pdf, etc. all break when decrypted. Is there anything I am doing wrong? Are these methods using binary to encrypt/decrypt the files? If not is there a way I can make it binary?
Any help is greatly appreciated!
public static void EncryptFile(string sInputFilename,
string sOutputFilename,
string sKey)
{
FileStream fsInput = new FileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
FileStream fsEncrypted = new FileStream(sOutputFilename,
FileMode.Create,
FileAccess.Write);
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransform desencrypt = DES.CreateEncryptor();
CryptoStream cryptostream = new CryptoStream(fsEncrypted,
desencrypt,
CryptoStreamMode.Write);
byte[] bytearrayinput = new byte[fsInput.Length];
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Close();
fsInput.Close();
fsEncrypted.Close();
}
public static void DecryptFile(string sInputFilename,
string sOutputFilename,
string sKey)
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
//A 64 bit key and IV is required for this provider.
//Set secret key For DES algorithm.
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
//Set initialization vector.
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
//Create a file stream to read the encrypted file back.
FileStream fsread = new FileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
//Create a DES decryptor from the DES instance.
ICryptoTransform desdecrypt = DES.CreateDecryptor();
//Create crypto stream set to read and do a
//DES decryption transform on incoming bytes.
CryptoStream cryptostreamDecr = new CryptoStream(fsread,
desdecrypt,
CryptoStreamMode.Read);
//Print the contents of the decrypted file.
StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
fsread.Close();
cryptostreamDecr.Close();
}
I don't know what the guy that wrote that article was smoking, but:
DESCryptoServiceProvider desCrypto =
(DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
will not get you a valid key. At least one problem is the fact that the key you use to encrypt is not the same key that you're using to decrypt, because you can't convert bytes to ASCII and back like that.
If you want to treat the key as a string, what you probably want is:
string keyAsString = Convert.ToBase64String(desCrypto.Key);
Then when you want to turn it back into bytes, instead of ASCIIEncoding.ASCII.GetBytes, you'll do:
byte[] key = Convert.FromBase64String(keyAsString);
EDIT
There's a ton more wrong with that article too. I'd say ignore that one and find a better example.
EDIT
Here's a very clean basic AES working example that I use for my standard encryption needs. Some of the major improvements over the article are:
Proper creation of a key
Current algorithm (AES 256-bit key)
Random IV
Buffered file access instead of reading/writing the entire file in one chunk
Wrapping all the disposable objects in using
Aside from that, it's the same basic idea.
using System;
using System.IO;
using System.Security.Cryptography;
namespace ConsoleApplication12
{
class Program
{
private const int KEY_SIZE_BYTES = 32;
private const int IV_SIZE_BYTES = 16;
static void Main(string[] args)
{
var rand = new Random();
using (var fs = File.Open(#"C:\temp\input.bin", FileMode.Create, FileAccess.Write, FileShare.None))
{
byte[] buffer = new byte[10000];
for (int i = 0; i < 100; ++i)
{
rand.NextBytes(buffer);
fs.Write(buffer, 0, buffer.Length);
}
}
string key = GenerateRandomKey();
Encrypt(#"C:\temp\input.bin", #"C:\temp\encrypted.bin", key);
Decrypt(#"C:\temp\encrypted.bin", #"C:\temp\decyrypted.bin", key);
}
static string GenerateRandomKey()
{
byte[] key = new byte[KEY_SIZE_BYTES];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(key);
}
return Convert.ToBase64String(key);
}
static void Encrypt(string inputFile, string outputFile, string key)
{
const int BUFFER_SIZE = 8192;
byte[] buffer = new byte[BUFFER_SIZE];
byte[] keyBytes = Convert.FromBase64String(key);
byte[] ivBytes = new byte[IV_SIZE_BYTES];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(ivBytes);
}
using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var outputStream = File.Open(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
outputStream.Write(ivBytes, 0, ivBytes.Length);
using (var cryptoAlgo = Aes.Create())
{
using (var encryptor = cryptoAlgo.CreateEncryptor(keyBytes, ivBytes))
{
using (var cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
{
int count;
while ((count = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
cryptoStream.Write(buffer, 0, count);
}
}
}
}
}
}
}
static void Decrypt(string inputFile, string outputFile, string key)
{
const int BUFFER_SIZE = 8192;
byte[] buffer = new byte[BUFFER_SIZE];
byte[] keyBytes = Convert.FromBase64String(key);
byte[] ivBytes = new byte[IV_SIZE_BYTES];
using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
inputStream.Read(ivBytes, 0, ivBytes.Length);
using (var outputStream = File.Open(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (var cryptoAlgo = Aes.Create())
{
using (var decryptor = cryptoAlgo.CreateDecryptor(keyBytes, ivBytes))
{
using (var cryptoStream = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read))
{
int count;
while ((count = cryptoStream.Read(buffer, 0, buffer.Length)) > 0)
{
outputStream.Write(buffer, 0, count);
}
}
}
}
}
}
}
}
}
Because the IV is random, you'll see another small difference in technique. When encrypting the file, you first write the IV to the encrypted file (it's not a secret, so you just write it straight out). When decrypting the file, you read the first few bytes to retrieve the IV, then the rest of the file contains the actual encrypted data. The purpose of a random IV is so the same plaintext file will encrypt into a different encrypted file every time you run it.
The Main method here demonstrates encryption with a random key. If you want to use a password, it's a little more work, but you can implement PBKDF2 with maybe a dozen or so extra lines of code.

how to encrypt/Decrypt .xlsx/.doc files with C#

I'm writing an application to Encrtpt/Decrypt files and using DESCryptoServiceProvider for this purpose. This seems to work for text files but when I use the same application for .xlsx file, the resulting encrypted file and the decrypted file get corrupted and I'm not able to open that any more. is there any way I can encryt / decrypt different kinds of file like .doc..xls etc.
update : added code for encryption/decryption
public static void EncryptFile(string filepath,string fileOutput, string key)
{
FileStream fsInput = new FileStream(filepath, FileMode.Open, FileAccess.Read);
FileStream fsEncrypted = new FileStream(fileOutput, FileMode.Create, FileAccess.Write);
DESCryptoServiceProvider DESc = new DESCryptoServiceProvider();
DESc.Key = ASCIIEncoding.ASCII.GetBytes(key);
DESc.IV = ASCIIEncoding.ASCII.GetBytes(key);
ICryptoTransform desEncrypt = DESc.CreateEncryptor();
CryptoStream cryptoStream = new CryptoStream(fsEncrypted, desEncrypt, CryptoStreamMode.Write);
byte[] byteArrayInput = new byte[fsInput.Length - 1];
fsInput.Read(byteArrayInput, 0, byteArrayInput.Length);
cryptoStream.Write(byteArrayInput, 0, byteArrayInput.Length);
cryptoStream.Close();
fsInput.Close();
fsEncrypted.Close();
}
public static void DecryptFile(string filepath, string fileOutput, string key)
{
DESCryptoServiceProvider DESc = new DESCryptoServiceProvider();
DESc.Key = ASCIIEncoding.ASCII.GetBytes(key);
DESc.IV = ASCIIEncoding.ASCII.GetBytes(key);
FileStream fsread = new FileStream(filepath, FileMode.Open, FileAccess.Read);
ICryptoTransform desDecrypt = DESc.CreateDecryptor();
CryptoStream cryptoStreamDcr = new CryptoStream(fsread, desDecrypt, CryptoStreamMode.Read);
StreamWriter fsDecrypted = new StreamWriter(fileOutput);
fsDecrypted.Write(new StreamReader(cryptoStreamDcr).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
}
static void Main(string[] args)
{
EncryptFile(#"C:\test1.xlsx", #"c:\test2.xlsx", "ABCDEFGH");
DecryptFile(#"C:\test2.xlsx", #"c:\test3.xlsx", "ABCDEFGH");
}
You are not encrypting or decrypting correctly. Encrypt -> Decrypt will always give a file identical to the input. If you post your code we may be able to assist in finding the bug in it.
You should use FileStreama as suggested in one of the comments by Kieren Johnstone. Also, you're not flushing the streams when encrypting - this may not be done automatically, so you should try and flush the streams, too.

Categories