I am creating a file using XmlWriter, XmlWriter writer = XmlWriter.Create(fileName); it is creating a file and then i have one more function which i am calling private void EncryptFile(string inputFile, string outputFile) which takes 2 string input and outpulfile and in the end i have two files one is encrypted and one is not. I just want one encrypted file but foor my encrypt function it takes inputfile which is created by XmlWriter. Is there any way i can create memorystream and pass that into my function instead of creating a inputfile.
my encrypt function
private void EncryptFile (string inputFile, string outputFile)
string password = #"fdds"; // Your Key Here
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
string cryptFile = outputFile;
FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,RMCrypto.CreateEncryptor(key,key),CryptoStreamMode.Write);
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
int data;
while ((data = fsIn.ReadByte()) != -1)
cs.WriteByte((byte)data);
cs.FlushFinalBlock();
fsIn.Close();
cs.Close();
fsCrypt.Close();
}
}
You can create an XmlWriter that writes to a memory stream:
var stream = new MemoryStream();
var writer = XmlWriter.Create(stream);
Now you can pass this stream to your EncryptFile function instead of an inputFile. You have to make sure that you don't forget these two things before reading the stream:
Make a call to writer.Flush() when you are done writing.
Set stream.Position back to 0 before you start reading the stream.
Related
I didn't want to seed the IV with the user given password. The question is if I've created the method of encrypting with a generated IV, is there anyway I could save the generated IV, to get it into the decryption method, without saving it into a database.
private void EncryptFile(string inputFile,string outputFile, string pass_input){
try
{
MessageBox.Show("FLAG 1");
UTF8Encoding UE = new UTF8Encoding();
//Represents a UTF-8 encoding of unicode characters
string password = pass_input;
// passed password through user input
byte[] key = UE.GetBytes(password);
//password parsed into bytes
string cryptFile = outputFile;
FileStream FScrypt = new FileStream(cryptFile, FileMode.Create);
//FScrypt is created where it creates a file to save output
RijndaelManaged RMcrypto = new RijndaelManaged();
//RMcrypto is created where new instance of RijndaelManaged Class is initialized
RMcrypto.GenerateIV();
CryptoStream cs = new CryptoStream(FScrypt, RMcrypto.CreateEncryptor(key,RMcrypto.IV), CryptoStreamMode.Write);
//CreateEncryptor from RMcrypto creates a symmetric Rijndael Encryptor object with specified key
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
//fsIn Opens the input file
MessageBox.Show("FLAG 2");
int data;
while ((data = fsIn.ReadByte()) != -1)
//will read input file opened by fsIn
cs.WriteByte((byte)data);
MessageBox.Show("FLAG 3");
fsIn.Close();
cs.Close();
FScrypt.Close();
catch(Exception ex)
{
MessageBox.Show("Failed");
}
}
private void DecryptFile(string inputFile, string outputFile, string pass_input)
{
try
{
string password = pass_input; // Taking password input and storing in local string.
UTF8Encoding UE = new UTF8Encoding() //UnicodeEncoding Object UTF8
byte[] key = UE.GetBytes(password); // converting password to bytes
FileStream fsCrypt = new FileStream(inputFile, FileMode.Open); // Opens the file
RijndaelManaged RMCrypto = new RijndaelManaged(); //new RijndaelMaaged object
CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(key, **"RMCrypto.IV"**), CryptoStreamMode.Read);
FileStream fsOut = new FileStream(outputFile, FileMode.Create);
int data;
while ((data = cs.ReadByte()) != -1)
fsOut.WriteByte((byte)data);
fsOut.Close();
cs.Close();
fsCrypt.Close();
}
catch (Exception ex)
{
MessageBox.Show("Failed");
}
}
One well used/accepted method is to prepend the IV to the encrypted data, the IV does not need to be secret.
I am attempting to copy a memory stream to a file stream. I noticed that the output exe is corrupt when decrypted. I am certain there is no issue with the decrypt function. Here is the code
private MemoryStream My_Encrypt(Stream inputFile)
{
//FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
MemoryStream fsCrypt = new MemoryStream();
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write);
int data;
while ((data = inputFile.ReadByte()) != -1)
cs.WriteByte((byte)data);
inputFile.Flush();
return fsCrypt;
}
MemoryStream ms = My_Encrypt(bundleStream);
ms.Seek(0, SeekOrigin.Begin);
FileStream atest = new FileStream("c:\\Somefile.exe",FileMode.Create);
ms.Seek(0, SeekOrigin.Begin);
ms.CopyTo(atest);
atest.Close();
More details:
The reason I am saying that the memory stream method is not working is because in My_Encrypt method if I replace fsCrypt with FileStream instead of Memory Stream and close fsCrypt at the end of the method and then reopen the saved file and write it to another file it works. My question is why is the memory stream method not working.
I believe you have to call FlushFinalBlock on the CryptoStream.
private MemoryStream My_Encrypt(Stream inputFile)
{
//FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
MemoryStream fsCrypt = new MemoryStream();
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write);
int data;
while ((data = inputFile.ReadByte()) != -1)
cs.WriteByte((byte)data);
cs.FlushFinalBlock();
return fsCrypt;
}
I made the following code to insert data to an encrypted xml file, I used a memory stream for the decrypted file and load it in a XmlDocument to add the required data, then encrypted it again back to the same file.
public static void IN_EncryptFile(MemoryStream FLin,string Path)
{
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(sKey);
string cryptFile = Path;
FileStream fsCrypt = new FileStream(cryptFile, FileMode.Open);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateEncryptor(key, key),
CryptoStreamMode.Write);
FLin.Position = 0;
int data;
while ((data = FLin.ReadByte()) != -1)
{
cs.WriteByte((byte)data);
}
FLin.Close();
FLin.Flush();
cs.Close();
fsCrypt.Close();
}
public static MemoryStream OUT_DecryptFile(string Path)
{
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(sKey);
FileStream fsCrypt = new FileStream(Path, FileMode.Open);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateDecryptor(key, key),
CryptoStreamMode.Read);
MemoryStream fsOut = new MemoryStream();
int data;
while ((data = cs.ReadByte()) != -1)
fsOut.WriteByte((byte)data);
cs.Close();
fsCrypt.Close();
fsOut.Position = 0;
return fsOut;
}
public static void Add_Data_XML()
{
string XML_Pt = #"C:\Test.Trr";
XmlDocument XDt = new XmlDocument();
XDt.Load(Cryption.OUT_DecryptFile(XML_Pt));
/// Adding XMl data
MemoryStream Fnl = new MemoryStream();
XDt.Save(Fnl);
Cryption.IN_EncryptFile(Fnl, XML_Pt);
Fnl.Flush();
Fnl.Close();
}
I need an opinion about the code as it works fine for me but sometimes it generates some errors in the encrypted file which I still don't fully understand why, but when I dencrypt the xml file I find the added data are in the wrong format and placed after the main XMl node as follow :
<Main_Node>
</Main_Node>”ÇÛÏ”ö8—´Ú·…ï/1Ž"‹ÓÃåõ¶—QÝUŸy…¤Êç‹íîzR߆ô
nÃFçiŽÌm–FÆzÍW9 úv¤ï_øVO,ÈvÄ
Your issue is that you use MemoryStream to store the temporary data and you read from it while you can. MemoryStream has an internal buffer that is larger than the data you write to it usually. So if you keep reading from it, you may get garbage data out from it. I would recommend not reading byte by byte from it, or at least get the actual length of the data and read that many bytes.
You also first close the MemoryStream and then flush it. This is pointless.
Another problem could be because you use FileMode.Open and write less than the previously existed in the file. This will leave existing data after what you write and that will show as garbage. Using FileMode.Create would be the right way here, since it means "if there is no file with this name, create a new one. If there is a file, truncate it."
FileMode documentation
But if you surely always write more than you read, then this shouldn't be an issue.
Also I wouldn't say "it works fine for me" if it actually has issues.
I think you have an encoding issue. Try this
MemoryStream ms = new MemoryStream();
XDt.Save(ms);
StreamReader Fnl = new StreamReader(ms, Encoding.UTF8);
okay so I have this code for decrypting files
public static byte[] DecryptFile(string inputFile, string skey)
{
RijndaelManaged aes = new RijndaelManaged();
byte[] key = ASCIIEncoding.UTF8.GetBytes(skey);
using (FileStream fsCrypt = new FileStream(inputFile, FileMode.Open))
{
using (CryptoStream cs =
new CryptoStream(fsCrypt, aes.CreateDecryptor(key, key),
CryptoStreamMode.Read))
{
using (BinaryReader reader = new BinaryReader(cs))
{
byte[] str = reader.ReadBytes(Convert.ToInt32(cs.Length));
reader.Close();
cs.Close();
return (str);
}
}
}
}
}
NOW i've got a problem with it, i can't determine the byte length! I tried
cs.Length
but it says the Stream doesn't support seeking (something like tht)
I also tried counting the bytes of the file by
File.ReadAllBytes(encrypted_file_path).Length
but it says the file is in use...it is indeed in use because of the FileStream fsCrypt
for the meantime I replaced cs.Length with some large integer to make it work..like 1000000..the maximum integer that doesn't cause any exception..it does work that way.
You cannot know the length until after you decrypt the entire file.
Therefore, you need to start with a small array, and make it bigger as it gets full.
The MemoryStream class does just that; you can just cs.CopyTo() into a new MemoryStream and call ToArray().
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.