///<summary> /// <para> /// This method encrypts the given input file in either of the 2 algorithms 'DES' or 'RC2'. /// Then it writes out the encrypted file /// </para> /// <para> /// This method first reads the input file to check to see if its already encrypted by this /// same program. If its already encrypted it gives a error. /// </para> /// <para> /// According to the algorithm specified it then encrypts the file. /// Also in the first 8 bytes of the new Encrypted it writes out "[saudes]" or "[saurc2]" /// This is done so the while decrypting the program can know which algorithm was used to /// encrypt the file. Also it used to check if the file has already encrypted /// </para> ///</summary> private void EncryptData() { //try-catch block try{ bool algo; //a boolean variable to check which algorithm to use in encrypting //open the 'FileStream' on the file to be encrypted FileStream fin = new FileStream(opent.Text, FileMode.Open, FileAccess.Read); //Make a file to save the encrypted data to and open a 'FileStream' on it FileStream fout = new FileStream(savet.Text, FileMode.OpenOrCreate, FileAccess.Write); //set the position of the 'cursor' to the start of the file fout.SetLength(0); //make a byte array of the size 64 bits //this is called the 'Buffer Size' of the algorithm //i.e. while encrypting blocks of the size 64bits are processed at a single time //later other blocks are of the same size. //we use 64bits because both 'DES' and 'RC2' both algorithms have 64 bit 'Buffer Size' byte[] bin = new byte[4096]; //set the total length of the file to me encrypted to a variable long totlen = fin.Length; long rdlen = 0; int len; //the code below is used to check if the file has already been encrypted by this program //make a byte array of length '4' byte[] tag = new byte[4]; //read the first 4 bytes from the file to be encrypted fin.Read(tag, 0, tag.Length); //if it contains the chars "[sau" then it has been already encrypted by this program if ((tag[0] == (byte)'[') && (tag[1] == (byte)'S') && (tag[2] == (byte)'a') && (tag[3] == (byte)'u')) { //genrate a error to let the user know of the error MessageBox.Show("This file is already Encrypted or in Invalid format!"); statusBar1.Text = "Error - Invalid File Format !!"; } else { //if the file if ok the proceed with encryption statusBar1.Text = "Encrypting..."; //set the file read cursor back to the 'Begning' of the opened file fin.Seek(0, SeekOrigin.Begin); } //make a object of the class 'SymmetricAlgorithm' SymmetricAlgorithm des; if (radioButton1.Checked) { //if the algorithm to be used is 'DES' then initilize the 'SymmetricAlgorithm' to 'DES_CSP' des = new DES_CSP(); //set the variable to true because we are using 'DES' algorithm. algo = true; } else { //if the algorithm to be used is 'RC2' then initilize the variable 'des' to 'RC2_CSP' des = new RC2_CSP(); //set the key size of the algorithm to 40 bits since we are using a 40 bit key des.KeySize = 40; //uncomment the below code to kind out the bits of keys supported by RC2 algorithm /*KeySizes[] ks = des.LegalKeySizes ; * Console.WriteLine("Key Sizes Supported :") ; * Console.WriteLIne("Minimum Size:" +ks[0].MinSize) ; * Console.WriteLine("Skip size of key: "+ks[0].SkipSize) ; * Console.WriteLine("Maximum Size: "+ks[0].MaxSize) ; */ //set the bool variable to false since we are using the RC2 algorithm algo = false; } //Make a object of the inner class 'StoreCryptoStream' we pass the bool variable //containing the algotithm information and the FileStream StoreCryptoStream scs = new StoreCryptoStream(algo, fout); //make an object of the 'SymmetricStreamEncryptor' class and pass it the 'Key and the 'Vector' //this starem helps to encrypt data according to the algorithm used SymmetricStreamEncryptor sse = des.CreateEncryptor(symKey, symIV); // a little extra feature here to show how to compose crypto // components that support ICryptoStream SHA1_CSP sha = new SHA1_CSP(); // wire up the encryptor - hash - StoreCryptoStream sse.SetSink(sha); sha.SetSource(sse); sha.SetSink(scs); scs.SetSource(sha); //read from the file to encrypt while (rdlen < totlen) { //set the number of bytes read len = fin.Read(bin, 0, 4096); //write the encrypted data sse.Write(bin, 0, len); //increase the size of bytes read rdlen = rdlen + len; } //free up the resources sse.CloseStream(); fin.Close(); fout.Close(); statusBar1.Text = "Encryption Compelete !"; } catch (Exception e) { MessageBox.Show("An exception occured while encrypting :" + e.ToString()); statusBar1.Text = "Error"; } }
///<summary> /// <para> /// This Method computes the 'Key' and the 'Initilization Vector' to be used in encrypting / decrypting. /// It generates the key according to the algorithm. /// It returns is key generation is sucessful /// </para> /// <para> /// If the algorithm to be used is 'DES' then it generates a 64bit Key and 64bit Vector /// from the provided 'Password' .Then this is stored in to a 'byte' array having 'length' '8'. /// since 1 byte = 8 bits , hence a byte array having length '8' will contain a key of /// 8 x 8 =64 bits. /// We use a 64bit key since DES supports a minimum 64 bit key /// </para > /// <para> /// If the algorithm to be used is 'RC2' then it generates a 40bit Key and a 40 bit Vector /// from the provided 'Password'. /// We use a 40 bit key here since RC2 supports a minimum 40 bit key (it does not support a 64bit key). /// </para> ///</summary> private bool GenerateKee(bool isDES) { //try-catch block try{ //store the password in a string string pass = passt.Text; int i; int len; //convert the password in to a Char array char[] cp = pass.ToCharArray(); len = cp.GetLength(0); //initilize a byte array byte[] bt = new byte[len]; //convert the Char array of the Password to a byte array for (i = 0; i < len; i++) { bt[i] = (byte)cp[i]; } //if we are producing a Key-Vector for the 'DES' algotithm if (isDES) { //initilize the byte arrays which will contain the 'Key' and the 'Vector' respectively //to a length of '8' (see above why we use a array of length '8') symKey = new byte[8]; symIV = new byte[8]; //make a instance of the class 'SHA1_CSP()' //this class is usefull in coverting 'byte' into 'Hash'. SHA1_CSP sha = new SHA1_CSP(); //write the Hash of the byte array containing the password sha.Write(bt); //close the stream sha.CloseStream(); //now Initilize the 'Key' array with the lower 64bits of the Hash of the 'Password' provided by the //user for (i = 0; i < 8; i++) { symKey[i] = sha.Hash[i]; } //initilize the 'Vector' array wiht the higher 64 bits of Hash of the 'Password' provided by //the user for (i = 8; i < 16; i++) { symIV[i - 8] = sha.Hash[i]; } } else { //if the algorithm is 'RC2' then genrate the following Key //inilize the Key and Vector arrays to a length of '5' (see above why we use '5') symKey = new byte[5]; symIV = new byte[5]; //make a instance of the class 'SHA1_CSP' //this class wreites the hash of a given byte SHA1_CSP sha = new SHA1_CSP(); //write the Hash of the byte array containing the user password sha.Write(bt); //close the stream sha.CloseStream(); //now Initilize the Key array to lower 40 bits of the Hash of the 'Password' provided by the user for (i = 0; i < 5; i++) { symKey[i] = sha.Hash[i]; } //initilize the Vector array to 40bits of hash for (i = 5; i < 10; i++) { symIV[i - 5] = sha.Hash[i]; } } //since every thing went properly return 'true' return(true); } catch (Exception e) { MessageBox.Show("A Exception Occured in Generating Keys :" + e.ToString()); //retuen false since there was a error return(false); } }