Exemple #1
0
        private void DecryptFile(string inFile, string ext)
        {
            start = DateTime.Now;
            Logger("Dec: Started on " + start.ToString("dd.MM.yyyy 'at' HH:mm:ss"));

            int    startFileName = inFile.LastIndexOf("\\") + 1;
            string shortFileName = inFile.Substring(startFileName, inFile.LastIndexOf(".") - startFileName) + ext;
            //string shortFileName = inFile.Substring(0, inFile.LastIndexOf(".")) + ext;
            string labelText = "Decrypting file \"" + shortFileName + "\"";

            // Create instance of Rijndael for
            // symetric decryption of the data.
            RijndaelManaged rjndl = new RijndaelManaged();

            rjndl.KeySize   = 256;
            rjndl.BlockSize = 256;
            rjndl.Mode      = CipherMode.CBC;

            // Create byte arrays to get the length of
            // the encrypted key and IV.
            // These values were stored as 4 bytes each
            // at the beginning of the encrypted package.
            byte[] LenK  = new byte[4];
            byte[] LenIV = new byte[4];

            // Consruct the file name for the decrypted file.
            string outFile = DecrFolder + shortFileName.Substring(0, shortFileName.LastIndexOf(".") - 1) + ext;

            // make sure directory exist
            try {
                Directory.CreateDirectory(DecrFolder);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Cannot create directory .\\Decrypt\r\n" + ex.Message);
                return;
            }

            // Use FileStream objects to read the encrypted
            // file (inFs) and save the decrypted file (outFs).
            try {
                using (FileStream inFs = new FileStream(inFile, FileMode.Open, FileAccess.Read, FileShare.Read, 8388608))
                {
                    inFs.Seek(0, SeekOrigin.Begin);
                    inFs.Seek(0, SeekOrigin.Begin);
                    inFs.Read(LenK, 0, 3);
                    inFs.Seek(4, SeekOrigin.Begin);
                    inFs.Read(LenIV, 0, 3);

                    // Convert the lengths to integer values.
                    int lenK    = BitConverter.ToInt32(LenK, 0);
                    int lenIV   = BitConverter.ToInt32(LenIV, 0);
                    int lenHash = 32;

                    // Create the byte arrays for
                    // the encrypted Rijndael key,
                    // the IV, and the hash.
                    byte[] KeyEncrypted = new byte[lenK];
                    byte[] IV           = new byte[lenIV];
                    byte[] hashRead     = new byte[lenHash];

                    // Extract the key, IV and hash
                    // starting from index 8
                    // after the length values.
                    inFs.Seek(8, SeekOrigin.Begin);
                    inFs.Read(KeyEncrypted, 0, lenK);
                    inFs.Seek(8 + lenK, SeekOrigin.Begin);
                    inFs.Read(IV, 0, lenIV);
                    inFs.Seek(8 + lenK + lenIV, SeekOrigin.Begin);
                    inFs.Read(hashRead, 0, lenHash);

                    Logger("Dec: hash declared = " + BitConverter.ToString(hashRead));

                    // check hash
                    // construct key for HMACSHA provider
                    byte[] hashKey = new byte[lenIV + 4];
                    IV.CopyTo(hashKey, 0);
                    byte[] pad = BitConverter.GetBytes(9);
                    pad.CopyTo(hashKey, (hashKey.Length - 4));

                    // make and compare hash
                    using (HMACSHA256 hmac = new HMACSHA256(hashKey))
                    {
                        // set position in stream
                        long dataIndex = LenK.Length + LenIV.Length + lenK + lenIV + lenHash;
                        inFs.Seek(dataIndex, SeekOrigin.Begin);

                        labelText = "Checking file integrity, please wait...";
                        backgroundWorker1.ReportProgress(0, labelText);

                        // generate hash
                        byte[] computedHash = hmac.ComputeHash(inFs);

                        Logger("Dec: hash computed = " + BitConverter.ToString(computedHash));

                        try
                        {
                            bool isHashOK = Enumerable.SequenceEqual(hashRead, computedHash);
                            if (!isHashOK)
                            {
                                backgroundWorker1.ReportProgress(-1);
                                Logger("Dec: hashes does not match");
                                labelText = "Cannot decrypt file. Integrity check ended up with false";
                                backgroundWorker1.ReportProgress(0, labelText);
                                throw new Exception("Cannot guarantee file integrity.\r\n" +
                                                    "Integrity check ended up with false"
                                                    );
                            }
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show(e.Message);
                            return;
                        }

                        Logger("Dec: hash OK");

                        labelText = "Decrypting file \"" + shortFileName + "\"";
                        backgroundWorker1.ReportProgress(0, labelText);
                    }

                    // Use RSACryptoServiceProvider
                    // to decrypt the Rijndael key.
                    byte[] KeyDecrypted;
                    try {
                        KeyDecrypted = rsa.Decrypt(KeyEncrypted, false);
                    }
                    catch (CryptographicException ce)
                    {
                        backgroundWorker1.ReportProgress(0, "Cannot decrypt file \"" + shortFileName + "\" with given key.");
                        inFs.Dispose();
                        backgroundWorker1.ReportProgress(-1);
                        MessageBox.Show("Data integrity is OK, but cannot decrypt!\r\nYou have probably wrong key!\r\nOfficial cause: " + ce.Message);
                        return;
                    }

                    // Decrypt the key.
                    ICryptoTransform transform = rjndl.CreateDecryptor(KeyDecrypted, IV);

                    // Determine the start postition of
                    // the ciphter text (startC)
                    // and its length(lenC).
                    int startC = LenK.Length + LenIV.Length + lenK + lenIV + lenHash;
                    int lenC   = (int)inFs.Length - startC;

                    // Decrypt the cipher text from
                    // from the FileSteam of the encrypted
                    // file (inFs) into the FileStream
                    // for the decrypted file (outFs).
                    using (FileStream outFs = new FileStream(outFile, FileMode.Create))
                    {
                        int count = 0;

                        // blockSizeBytes can be any arbitrary size.
                        int    blockSizeBytes = rjndl.BlockSize / 8;
                        byte[] data           = new byte[blockSizeBytes];

                        // By decrypting a chunk a time,
                        // you can save memory and
                        // accommodate large files.

                        // Start at the beginning
                        // of the cipher text.
                        inFs.Seek(startC, SeekOrigin.Begin);
                        using (CryptoStream outStreamDecrypted = new NotClosingCryptoStream(outFs, transform, CryptoStreamMode.Write))
                        {
                            double fileLength = lenC;//inFs.Length;
                            double blocks     = fileLength / blockSizeBytes;
                            int    step       = (int)Math.Ceiling(blocks) / 128;
                            if (step < 1)
                            {
                                step = 1;
                            }
                            int iteration = 1;

                            do
                            {
                                count = inFs.Read(data, 0, blockSizeBytes);
                                outStreamDecrypted.Write(data, 0, count);

                                if (iteration++ % step == 0)
                                {
                                    backgroundWorker1.ReportProgress(1);    //increment progressBar and NOT change label1
                                }
                            }while (count > 0);

                            backgroundWorker1.ReportProgress(100);  //set 100% full progress bar due to very small files
                        }//CryptoStream

                        Logger("Dec: Decrypted file length = " + outFs.Length);

                        outFs.Close();
                    }//outFs
                    inFs.Close();

                    labelText = "Decryption of \"" + shortFileName + "\" was succesful";
                    backgroundWorker1.ReportProgress(0, labelText);

                    Logger("Dec: Decryption was succesful");
                    finish = DateTime.Now;

                    TimeSpan duration = finish.Subtract(start);
                    Logger("Dec: Finished on " + finish.ToString("dd.MM.yyyy 'at' HH:mm:ss"));
                    Logger("File \"" + inFile + "\"\r\n     decrypted in " +
                           duration.Days + " days, " +
                           duration.Hours + ":" +
                           duration.Minutes + ":" + duration.Seconds +
                           "." + duration.Milliseconds +
                           "\r\n=================================================="
                           );
                }
            }
            catch (Exception exc)
            {
                backgroundWorker1.ReportProgress(-1);
                backgroundWorker1.ReportProgress(0, "Error occured in decrypt process");
                MessageBox.Show("Error occured in decrypt process" + exc.GetType() + "\r\n" + exc.Message);
            }
        }
Exemple #2
0
        private void EncryptFile(string inFile, string ext)
        {
            start = DateTime.Now;
            Logger("Enc: Started on " + start.ToString("dd.MM.yyyy 'at' HH:mm:ss"));

            int    startFileName = inFile.LastIndexOf("\\") + 1;
            string shortFileName = inFile.Substring(startFileName, inFile.LastIndexOf(".") - startFileName) + ext;
            // Change the file's extension to ".enc"
            string outFile = EncrFolder + inFile.Substring(startFileName, inFile.LastIndexOf(".") - startFileName) + "C" + ext;

            // make sure directory exist
            try {
                Directory.CreateDirectory(EncrFolder);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Cannot create directory .\\Encrypt\r\n" + ex.Message);
                return;
            }

            string labelText = "Encrypting file \"" + shortFileName + "\"";

            backgroundWorker1.ReportProgress(0, labelText);

            // Create instance of Rijndael for
            // symetric encryption of the data.
            RijndaelManaged rjndl = new RijndaelManaged();

            rjndl.KeySize   = 256;
            rjndl.BlockSize = 256;
            rjndl.Mode      = CipherMode.CBC;
            ICryptoTransform transform = rjndl.CreateEncryptor();

            // Use RSACryptoServiceProvider to
            // enrypt the Rijndael key.
            // rsa is previously instantiated:
            //    rsa = new RSACryptoServiceProvider(cspp);
            byte[] keyEncrypted = rsa.Encrypt(rjndl.Key, false);

            // Create byte arrays to contain
            // the length values of the key and IV.
            byte[] LenK  = new byte[4];
            byte[] LenIV = new byte[4];

            int lKey = keyEncrypted.Length;

            LenK = BitConverter.GetBytes(lKey);
            int lIV = rjndl.IV.Length;

            LenIV = BitConverter.GetBytes(lIV);

            // prepare 32B dummyHash
            byte[] dummyHash = new byte[32];
            byte[] pad       = BitConverter.GetBytes(9);

            // Write the following to the FileStream
            // for the encrypted file (outFs):
            // - length of the key
            // - length of the IV
            // - ecrypted key
            // - the IV
            // - dummyHash to check integrity
            // - the encrypted cipher content
            // --- rewrite dummyHash with true hash of encrypted data

            try {
                using (FileStream outFs = new FileStream(outFile, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 8388608))
                {
                    outFs.Write(LenK, 0, 4);
                    outFs.Write(LenIV, 0, 4);
                    outFs.Write(keyEncrypted, 0, lKey);
                    outFs.Write(rjndl.IV, 0, lIV);

                    // write dummyHash
                    outFs.Write(dummyHash, 0, dummyHash.Length);

                    // Now write the cipher text using
                    // a CryptoStream for encrypting.
                    using (CryptoStream outStreamEncrypted = new NotClosingCryptoStream(outFs, transform, CryptoStreamMode.Write))
                    {
                        // By encrypting a chunk at
                        // a time, you can save memory
                        // and accommodate large files.
                        int  count  = 0;
                        long offset = 0;

                        // blockSizeBytes can be any arbitrary size.
                        int    blockSizeBytes = rjndl.BlockSize / 8;
                        byte[] data           = new byte[blockSizeBytes];
                        int    bytesRead      = 0;

                        using (FileStream inFs = new FileStream(inFile, FileMode.Open, FileAccess.Read, FileShare.Read, 8388608))
                        {
                            double fileLength = inFs.Length;
                            double blocks     = fileLength / blockSizeBytes;
                            int    step       = (int)Math.Ceiling(blocks) / 128;
                            if (step < 1)
                            {
                                step = 1;
                            }
                            int iteration = 1;
                            do
                            {
                                count   = inFs.Read(data, 0, blockSizeBytes);
                                offset += count;
                                outStreamEncrypted.Write(data, 0, count);
                                bytesRead += blockSizeBytes;

                                if (iteration++ % step == 0)
                                {
                                    backgroundWorker1.ReportProgress(1);    //increment progressBar and NOT change label1
                                }
                            }while (count > 0);

                            backgroundWorker1.ReportProgress(100);               //set 100% full progress bar due to very small files

                            Logger("Enc: Original file length = " + fileLength); //dlzka cisteho suboru

                            inFs.Close();
                        } // FileStream inFs
                    }     // CryptoStream outStreamEncrypted

                    labelText = "Computing HMAC hash";
                    backgroundWorker1.ReportProgress(0, labelText);

                    // generate initialization key for HMACSHA256 provider
                    byte[] hashKey = new byte[lIV + 4];
                    rjndl.IV.CopyTo(hashKey, 0);
                    pad.CopyTo(hashKey, (hashKey.Length - 4));

                    // make and reWrite hash
                    using (HMACSHA256 hmac = new HMACSHA256(hashKey))
                    {
                        // set position in stream
                        long dataIndex = LenK.Length + LenIV.Length + lKey + lIV + dummyHash.Length;
                        outFs.Seek(dataIndex, SeekOrigin.Begin);

                        // generate hash
                        dummyHash = hmac.ComputeHash(outFs);

                        Logger("Enc: hash = " + BitConverter.ToString(dummyHash));

                        // write hash
                        dataIndex -= dummyHash.Length;
                        outFs.Seek(dataIndex, SeekOrigin.Begin);
                        outFs.Write(dummyHash, 0, dummyHash.Length);

                        //erase hash from memory
                        for (int i = 0; i < 32; i += 4)
                        {
                            pad.CopyTo(dummyHash, i);
                        }
                    }//HMACSHA256

                    Logger("Enc: Encrypted file length = " + outFs.Length);

                    labelText = "Encryption was succesful";
                    backgroundWorker1.ReportProgress(0, labelText);

                    outFs.Close();
                    Logger("Enc: Encryption was succesful");

                    finish = DateTime.Now;
                    TimeSpan duration = finish.Subtract(start);
                    Logger("Enc: Finished on " + finish.ToString("dd.MM.yyyy 'at' HH:mm:ss"));
                    Logger("File \"" + inFile + "\"\r\n     encrypted in " +
                           duration.Days + " days, " +
                           duration.Hours + ":" +
                           duration.Minutes + ":" + duration.Seconds +
                           "." + duration.Milliseconds +
                           "\r\n=================================================="
                           );
                }//outFs
            }
            catch (Exception exc)
            {
                backgroundWorker1.ReportProgress(-1);
                backgroundWorker1.ReportProgress(0, "Error occured in encrypt process");
                MessageBox.Show("Error occured in encrypt process\r\n" + exc.GetType() + "\r\n" + exc.Message);
            }
        }