Same KEY & IV for TripleDES Encryption as well as Decryption in 2 different Win Services.

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.



Answer this question

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

    Ok. I will be waiting for your next reply. Thanks.
  • 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

    Thanks Stefan. I will try to implement your solution and will get back soon.
  • Adarsh123

    After you generate the keys in Service1 you can convert them to strings and send them by remoting to Service2.

    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

    All you have to do is embed the public key in the WinService1 and private key in WinService2... I will write for you a class that will do all of this but later becouse I have problems on my own with tcp remoting.

  • anand sivaraman

    I don't understand why anyone would want to save a file that have no inteligible data. The save action of the notepad can modify the content if the content is saved as Unicode by C# and notepad saves it as asci...

    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.



  • Same KEY & IV for TripleDES Encryption as well as Decryption in 2 different Win Services.