Hi,
I want to encrypt as well as decrypt a file using TripleDES. My problem is that I am autogenerating the KEY & IV while encrypting the files. As per my project requirement, I have to keep both Encryption & Decryption parts in two differents windows services. Can any one please guide me how to supply same KEY & IV for both I am using the following coding for encryption & decryption:
//.......................... private static void EncryptData(String inName, String outName, byte[] tdesKey, byte[] tdesIV){
//Create the file streams to handle the input and output files.FileStream fin =
new FileStream(inName, FileMode.Open, FileAccess.Read);FileStream fout =
new FileStream(outName, FileMode.OpenOrCreate, FileAccess.Write);fout.SetLength(0);
//Create variables to help with read and write. byte[] bin = new byte[100]; //This is intermediate storage for the encryption. long rdlen = 0; //This is the total number of bytes written. long totlen = fin.Length; //This is the total length of the input file. int len; //This is the number of bytes to be written at a time.TripleDESCryptoServiceProvider tdes =
new TripleDESCryptoServiceProvider();CryptoStream encStream =
new CryptoStream(fout, tdes.CreateEncryptor(tdesKey, tdesIV), CryptoStreamMode.Write);Console.WriteLine("Encrypting...");
//Read from the input file, then encrypt and write to the output file. while(rdlen < totlen){
len = fin.Read(bin, 0, 100);
encStream.Write(bin, 0, len);
rdlen = rdlen + len;
Console.WriteLine("{0} bytes processed", rdlen);
}
encStream.Close();
}
//.......................... private static void DecryptData(String inName, String outName, byte[] tdesKey, byte[] tdesIV){
//Create the file streams to handle the input and output files.FileStream fin =
new FileStream(inName, FileMode.Open, FileAccess.Read);FileStream fout =
new FileStream(outName, FileMode.OpenOrCreate, FileAccess.Write);fout.SetLength(0);
//Create variables to help with read and write. byte[] bin = new byte[100]; //This is intermediate storage for the encryption. long rdlen = 0; //This is the total number of bytes written. long totlen = fin.Length; //This is the total length of the input file. int len; //This is the number of bytes to be written at a time.TripleDESCryptoServiceProvider tdes =
new TripleDESCryptoServiceProvider();CryptoStream encStream =
new CryptoStream(fout, tdes.CreateDecryptor(tdesKey, tdesIV), CryptoStreamMode.Write);Console.WriteLine("Encrypting...");
//Read from the input file, then encrypt and write to the output file. while(rdlen < totlen){
len = fin.Read(bin, 0, 100);
encStream.Write(bin, 0, len);
rdlen = rdlen + len;
Console.WriteLine("{0} bytes processed", rdlen);
}
encStream.Close();
}
//..........................For calling Encryption, I am using the following for Key & IV:
TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider();
tDESalg .Key & tDESalg .IV
Kindly tell me the solution.
NOTE: My encryption &decryption methods can't be called from one windows service.
Thanks & Regards,
Lita.

Same KEY & IV for TripleDES Encryption as well as Decryption in 2 different Win Services.
Michael Klucher - MSFT
Thanks again Stefan. Sorry for troubling you so much. Actually my project requirement is to maintain TripleDES standard for encryption. I am completely new to this subject and I am not able to clarify all my doubts even though I am refering MSDN. I thought if I use TripleDES for encryption then it will satisfy the project requirement. As you know, my application is not a web based application. So, do I need to implement RSA also Honestly speaking, I am not at all clear about RSA. Where does it fit in my existing encryption/decryption coding Or do you mean that the above coding for RSA is meant to generate the private & public keys files. If I need to create these two xml files for public & private keys then I suppose I need to replace my existing coding for serialize/desrialization (the coding you mentioned in your previous reply) with your recent coding for RSA.
If all of my above assumtions are right then I would like to clarify the following:
In my existing coding, I am keeping the encrypted file & it's serialized key file in the same place and in case I implement RSA & create both public/private key files then also I am going to keep them in the same folder. So, what extra advantage would I get if I replace my existing coding with RSA coding I think, public/private concept makes the encryption more secure if we keep the private key in a completely secured place where only few people will have access to it. But in this case, I need to provide the path of both public & private files and as far as I know both the key files have to be kept in the same server (even in same folder also).
Hope you won't mind to clarify all my doubts... THANKS A LOT for your constant help.
Danny Tuppeny
Hi Stefan,
Thanks for the response. Actually, Service1 wakes up once in every 2 minutes. But Service2 has to wake up once in a week. So, how can I send them through remoting to service2 Moreover, Key & IV would be regenerated everytime Service1 woke up. So, if one file was encrypted today by service1 then that file may need to get decrypted after 7 days by Service2.
Please suggest.
Regards,
Lita
Lincbarr
Hi Stefan,
I am waiting for your reply. Please post the coding when you get time. Hope your remoting issue is resolved.
Thanks & Regards,
Lita
melonboy
Stefan, one more thing. Just want to verify. In case some one opened the .enc/.keys file in a notepad and saved it while closing the file(even though he didn't make any changes to the contents of either .enc or .keys file) then these files would become invalid and we won't be able to decrypt them again. Am I right If it's right then do we have any way to avoid this issue.
**Please look at my previous question also which is related to RSA.
Thanks a lot for your help.
Jassim Rahma
DJV
Hi Stefan,
Thanks a lot. It's working fine. But please help me to understand RSA. I am new to this concept. My applications are windows services. Do I still need to implement any additional thing for security Your coding is working fine. But as I do not have any idea about RSA that's why I am waiting for further guidance from you. Please don't mind if it sounds very silly.
Regards,
Lita.
Spenceee
Adarsh123
In Service1 :
string key = BitConverter.ToString(tDESalg.Key);
string iv = BitConverter.ToString(tDESalg.IV);
In Service2 you can marshal an object that expose a method like:
SetKeys(string key, string iv)
{
byte[] key = BitConverter.GetBytes(key);
byte[]iv = BitConverter.GetBytes(iv);
}
One more thing, you should use RSA to ecrypt the 2 strings so no one can see them.
Viral Thakkar
anand sivaraman
Now on RSA:
1. Generate RSA keys and save them to xml:
/// <summary>
/// Generates 2 XML files (public and private key)
/// </summary>
/// <param name="privateKeyPath">RSA private key file path</param>
/// <param name="publicKeyPath">RSA private key file path</param>
/// <param name="size">secure size must be above 1024</param>
public static void RsaGen(string privateKeyPath, string publicKeyPath, int size)
{
//stream to save the keys
FileStream fs = null;
StreamWriter sw = null;
//create RSA provider
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(size);
try
{
//save private key
fs = new FileStream(privateKeyPath, FileMode.Create, FileAccess.Write);
sw = new StreamWriter(fs);
sw.Write(rsa.ToXmlString(true));
sw.Flush();
}
finally
{
if (sw != null) sw.Close();
if(fs != null) fs.Close();
}
try
{
//save public key
fs = new FileStream(publicKeyPath, FileMode.Create, FileAccess.Write);
sw = new StreamWriter(fs);
sw.Write(rsa.ToXmlString(false));
sw.Flush();
}
finally
{
if (sw != null) sw.Close();
if (fs != null) fs.Close();
}
rsa.Clear();
}
2.Read this msdn article to learn how to use RSACryptoServiceProvider for ecryption / decryption.
hazz
Ok, so you can create a struct and for each pair of keys, Service1 will serialize on the disk the pair. Then when Service2 wakes up he can access the keys from disk(you'll have file1.enc & file1.keys on disk).
Code:
using
System;using
System.Collections.Generic;using
System.Text;using
System.IO;using
System.Runtime.Serialization.Formatters.Binary;[
Serializable]public
struct KeyContainer{
byte[] key; byte[] iv; public byte[] Key{
get { return this.key; }}
public byte[] IV{
get { return this.iv; }}
public KeyContainer(byte[] key, byte[] iv){
this.key = key; this.iv = iv;}
public KeyContainer(string filePath){
this = Deserialize(filePath);}
public static KeyContainer Deserialize(string filePath){
KeyContainer obj = new KeyContainer(); using (Stream stream = File.Open(filePath, FileMode.Open)){
BinaryFormatter bf = new BinaryFormatter();obj = (
KeyContainer)bf.Deserialize(stream);}
return obj;}
public void Serialize(string filePath){
string retError = string.Empty; using (Stream stream = File.Open(filePath, FileMode.Create)){
BinaryFormatter bf = new BinaryFormatter();bf.Serialize(stream,
this);}
}
}
So Service1 will use the KeyContainer(byte[] key, byte[] iv) constructor and Service2 will load the struct from disk using KeyContainer(string filePath) contructor. After Service1 serialize on disk the struct you shoud ecrypt the file with RSA, so Service1 & Service2 shoud share same RSA pair to ecript / decript keys. I hope this will help.