Ejemplo n.º 1
0
        /// <summary>
        /// 压缩2
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte[] DeflateByte(byte[] str)
        {
            if (str == null)
            {
                return null;
            }
            //这里要添加库Ionic
            using (var output = new MemoryStream())
            {
                using (
                  var compressor = new Ionic.Zlib.DeflateStream(
                  output, Ionic.Zlib.CompressionMode.Compress,
                  Ionic.Zlib.CompressionLevel.BestSpeed))
                {
                    compressor.Write(str, 0, str.Length);
                }

                return output.ToArray();
            }

            //当然如果使用GZIP压缩的话,只需要将
            //new Ionic.Zlib.DeflateStream( 改为
            //new Ionic.Zlib.GZipStream(,然后
            //actContext.Response.Content.Headers.Add("Content-encoding", "deflate");改为
            //actContext.Response.Content.Headers.Add("Content-encoding", "gzip");
            //就可以了,经本人测试,
            //Deflate压缩要比GZIP压缩后的代码要小,所以推荐使用Deflate压缩
        }
Ejemplo n.º 2
0
		/// <summary>
		/// Gets the response stream with HTTP decompression.
		/// </summary>
		/// <param name="response">The response.</param>
		/// <returns></returns>
		public static Stream GetResponseStreamWithHttpDecompression(this WebResponse response)
		{
			var stream = response.GetResponseStream();
			var encoding = response.Headers["Content-Encoding"];
			if (encoding != null && encoding.Contains("gzip"))
				stream = new Ionic.Zlib.GZipStream(stream, Ionic.Zlib.CompressionMode.Decompress);
			else if (encoding != null && encoding.Contains("deflate"))
				stream = new Ionic.Zlib.DeflateStream(stream, Ionic.Zlib.CompressionMode.Decompress);
			return stream;
		}
Ejemplo n.º 3
0
        public static byte[] CompressDeflate(byte[] bytes)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                using (Ionic.Zlib.DeflateStream zip = new Ionic.Zlib.DeflateStream(ms, Ionic.Zlib.CompressionMode.Compress, true))
                {
                    zip.Write(bytes, 0, bytes.Length);
                }

                return ms.ToArray();
            }
        }
Ejemplo n.º 4
0
        public static byte[] CompressDeflate(string ResponseData, Encoding e)
        {
            Byte[] bytes = e.GetBytes(ResponseData);

            using (MemoryStream ms = new MemoryStream())
            {

                using (Ionic.Zlib.DeflateStream zip = new Ionic.Zlib.DeflateStream(ms, Ionic.Zlib.CompressionMode.Compress, true))
                {
                    zip.Write(bytes, 0, bytes.Length);
                }

                return ms.ToArray();

            }
        }
Ejemplo n.º 5
0
        public static byte[] DeflateByte(byte[] str)
        {
            if (str == null)
            {
                return null;
            }

            using (var output = new MemoryStream())
            {
                using (var compressor = new Ionic.Zlib.DeflateStream(output, Ionic.Zlib.CompressionMode.Compress, Ionic.Zlib.CompressionLevel.BestSpeed))
                {
                    compressor.Write(str, 0, str.Length);
                }

                return output.ToArray();
            }
        }
Ejemplo n.º 6
0
        public static async Task<byte[]> CompressionByteAsync(byte[] str, CompressionType compressionType)
        {
            if (str == null)
            {
                return null;
            }

            using (var output = new MemoryStream())
            {
                switch (compressionType)
                {
                    case CompressionType.Deflate:
                        using (
                            var compressor = new Ionic.Zlib.DeflateStream(
                            output, Ionic.Zlib.CompressionMode.Compress,
                            Ionic.Zlib.CompressionLevel.BestSpeed))
                        {
                            await compressor.WriteAsync(str, 0, str.Length);
                            //compressor.Write(str, 0, str.Length);
                        }
                        break;
                    case CompressionType.GZip:
                        using (
                            var compressor = new Ionic.Zlib.GZipStream(
                            output, Ionic.Zlib.CompressionMode.Compress,
                            Ionic.Zlib.CompressionLevel.BestSpeed))
                        {
                            await compressor.WriteAsync(str, 0, str.Length);
                            //compressor.Write(str, 0, str.Length);
                        }
                        break;
                    case CompressionType.Zlib:
                        using (
                            var compressor = new Ionic.Zlib.ZlibStream(
                            output, Ionic.Zlib.CompressionMode.Compress,
                            Ionic.Zlib.CompressionLevel.BestSpeed))
                        {
                            await compressor.WriteAsync(str, 0, str.Length);
                            //compressor.Write(str, 0, str.Length);
                        }
                        break;
                }

                return output.ToArray();
            }
        }
Ejemplo n.º 7
0
        public static byte[] DecompressDeflate(Stream input)
        {
            using (Ionic.Zlib.DeflateStream decompressor = new Ionic.Zlib.DeflateStream(input, Ionic.Zlib.CompressionMode.Decompress))
            {
                int read = 0;
                var buffer = new byte[BUFFER_SIZE];

                using (MemoryStream output = new MemoryStream())
                {
                    while ((read = decompressor.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        output.Write(buffer, 0, read);
                    }
                    return output.ToArray();
                }
            }
        }
        public static byte[] DeflateByte(byte[] str)
        {
            if (str == null)
            {
                return(null);
            }

            using (var output = new MemoryStream())
            {
                using (
                    var compressor = new Ionic.Zlib.DeflateStream(
                        output, Ionic.Zlib.CompressionMode.Compress,
                        Ionic.Zlib.CompressionLevel.BestSpeed))
                {
                    compressor.Write(str, 0, str.Length);
                }

                return(output.ToArray());
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Compress bytes using zlib compression
        /// </summary>
        /// <param name="decompressedBytes"></param>
        /// <param name="compressedBytes"></param>
        /// <returns></returns>
        public static byte[] CompressZLib(byte[] decompressedBytes, out int compressedBytes)
        {
            var msDecompressed = new MemoryStream(decompressedBytes);
            // We must skip the first two bytes
            // See http://george.chiramattel.com/blog/2007/09/deflatestream-block-length-does-not-match.html
            // EAT the zlib headers, the rest is a normal 'deflate'd stream
            //msDecompressed.ReadByte();
            //msDecompressed.ReadByte();

            //var msInflated = new MemoryStream((int)(msCompressed.Length * 2));
            //var newBytes = new byte[msCompressed.Length * 2];
            var newBytes = new byte[decompressedBytes.Length];

            // TODO: Add the zlib headers to the data....
            // TODO: Also need the Adler32 Checksum at the end...

            var deflate2 = new Ionic.Zlib.DeflateStream(msDecompressed, Ionic.Zlib.CompressionMode.Compress);

            deflate2.Read(newBytes, 0, decompressedBytes.Length);

            // The last 32 bits (4 bytes) are supposed to be an Adler-32 checksum. Might need to remove them as well.
            using (var deflater = new DeflateStream(msDecompressed, CompressionMode.Compress))
            {
                compressedBytes = deflater.Read(newBytes, 0, decompressedBytes.Length) + 2;

                //while (inflater.CanRead)
                //{
                //  var readBytes = new byte[4095];
                //  // Should be able to change to just this.
                //  var bytesRead = inflater.Read(readBytes, 0, readBytes.Length);
                //  if (bytesRead != 0)
                //  {
                //      msInflated.Write(readBytes, 0, bytesRead);
                //  }
                //}
            }
            //newBytes = new byte[msInflated.Length];
            //msInflated.Read(newBytes, 0, (int)msInflated.Length);
            return(newBytes);
        }
Ejemplo n.º 10
0
 public static void CompressByte(byte[] sourceByte, out byte[] dataByte)
 {
     dataByte = null;
     Ionic.Zlib.DeflateStream compressByte = null;
     try{
         using (MemoryStream ms = new MemoryStream())
         {
             using (compressByte = new Ionic.Zlib.DeflateStream(ms, Ionic.Zlib.CompressionMode.Compress, true))
             {
                 compressByte.Write(sourceByte, 0, sourceByte.Length);
             }
             dataByte = ms.ToArray();
         }
     }catch (ApplicationException ex) {
         Console.WriteLine("compress byte is exception !!");
     }finally{
         if (compressByte != null)
         {
             compressByte.Close();
         }
     }
 }
Ejemplo n.º 11
0
        public static byte[] DecryptData(ref byte[] data, string password, RijndaelManaged aes)
        {
            int len = 0;

            byte[] buffer = new byte[aes.BlockSize / 8];
            byte[] salt   = new byte[aes.KeySize / 8];
            byte[] iv     = new byte[aes.BlockSize / 8];
            byte[] decryptedData;

            using (MemoryStream inms = new MemoryStream(data))
            {
                inms.Read(salt, 0, salt.Length);
                inms.Read(iv, 0, iv.Length);
                aes.IV = iv;

                Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(password, salt, 1000);
                aes.Key = deriveBytes.GetBytes(salt.Length);

                //Decryption interface.
                using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
                    using (CryptoStream cse = new CryptoStream(inms, decryptor, CryptoStreamMode.Read))
                        using (MemoryStream outms = new MemoryStream())
                        {
                            //using (DeflateStream ds = new DeflateStream(cse, CompressionMode.Decompress, false))
                            using (Ionic.Zlib.DeflateStream ds = new Ionic.Zlib.DeflateStream(cse, Ionic.Zlib.CompressionMode.Decompress))
                            {
                                while ((len = ds.Read(buffer, 0, buffer.Length)) > 0)
                                {
                                    outms.Write(buffer, 0, len);
                                }
                            }

                            decryptedData = outms.ToArray();
                        }

                return(decryptedData);
            }
        }
Ejemplo n.º 12
0
        private Stream MaybeApplyCompression(Stream s, long streamLength)
        {
            if (_CompressionMethod == 0x08 && CompressionLevel != Ionic.Zlib.CompressionLevel.None)
            {
#if !NETCF
                // ParallelDeflateThreshold == 0    means ALWAYS use parallel deflate
                // ParallelDeflateThreshold == -1L  means NEVER use parallel deflate
                // Other values specify the actual threshold.
                if (_container.ParallelDeflateThreshold == 0L ||
                    (streamLength > _container.ParallelDeflateThreshold &&
                     _container.ParallelDeflateThreshold > 0L))
                {
                    // This is sort of hacky.
                    //
                    // It's expensive to create a ParallelDeflateOutputStream, because
                    // of the large memory buffers.  But the class is unlike most Stream
                    // classes in that it can be re-used, so the caller can compress
                    // multiple files with it, one file at a time.  The key is to call
                    // Reset() on it, in between uses.
                    //
                    // The ParallelDeflateOutputStream is attached to the container
                    // itself - there is just one for the entire ZipFile or
                    // ZipOutputStream. So it gets created once, per save, and then
                    // re-used many times.
                    //
                    // This approach will break when we go to a "parallel save"
                    // approach, where multiple entries within the zip file are being
                    // compressed and saved at the same time.  But for now it's ok.
                    //

                    // instantiate the ParallelDeflateOutputStream
                    if (_container.ParallelDeflater == null)
                    {
                        _container.ParallelDeflater =
                            new Ionic.Zlib.ParallelDeflateOutputStream(s,
                                                                       CompressionLevel,
                                                                       _container.Strategy,
                                                                       true);
                        // can set the codec buffer size only before the first call to Write().
                        if (_container.CodecBufferSize > 0)
                            _container.ParallelDeflater.BufferSize = _container.CodecBufferSize;
                        if (_container.ParallelDeflateMaxBufferPairs > 0)
                            _container.ParallelDeflater.MaxBufferPairs =
                                _container.ParallelDeflateMaxBufferPairs;
                    }
                    // reset it with the new stream
                    Ionic.Zlib.ParallelDeflateOutputStream o1 = _container.ParallelDeflater;
                    o1.Reset(s);
                    return o1;
                }
#endif
                var o = new Ionic.Zlib.DeflateStream(s, Ionic.Zlib.CompressionMode.Compress,
                                                     CompressionLevel,
                                                     true);
                if (_container.CodecBufferSize > 0)
                    o.BufferSize = _container.CodecBufferSize;
                o.Strategy = _container.Strategy;
                return o;
            }


#if BZIP
            if (_CompressionMethod == 0x0c)
            {
#if !NETCF
                if (_container.ParallelDeflateThreshold == 0L ||
                    (streamLength > _container.ParallelDeflateThreshold &&
                     _container.ParallelDeflateThreshold > 0L))
                {

                    var o1 = new Ionic.BZip2.ParallelBZip2OutputStream(s, true);
                    return o1;
                }
#endif
                var o = new Ionic.BZip2.BZip2OutputStream(s, true);
                return o;
            }
#endif

            return s;
        }
Ejemplo n.º 13
0
        /// <summary>
        /// The encrypted file by AES (exactly Rijndael) to the original file or folder by user's password.
        /// ユーザーが設定したパスワードによって、AES(正確にはRijndael)によって暗号化されたファイルを
        /// 元のファイル、またはフォルダーに復号して戻す。
        /// </summary>
        /// <param name="FilePath">File path or directory path is encrypted</param>
        /// <param name="OutFileDir">The directory of outputing encryption file.</param>
        /// <param name="Password">Encription password string</param>
        /// <returns>bool true: Success, false: Failed</returns>
        public bool Decrypt(
      object sender, DoWorkEventArgs e,
      string FilePath, string OutDirPath, string Password, byte[] PasswordBinary, Action<int, string> dialog)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
              worker.WorkerSupportsCancellation = true;

              //-----------------------------------
              // Header data is starting.
              // Progress event handler
              ArrayList MessageList = new ArrayList();
              MessageList.Add(READY_FOR_DECRYPT);
              MessageList.Add(Path.GetFileName(FilePath));
              worker.ReportProgress(0, MessageList);

              int len = 0;
              byte[] byteArray;

              List<string> FileList = new List<string>();
              Dictionary<int, FileListData> dic = new Dictionary<int, FileListData>();

              if (_TokenStr.Trim() == "_AttacheCaseData")
              {
            // Atc data
              }
              else if (_TokenStr.Trim() == "_Atc_Broken_Data")
              {
            // Atc file is broken
            e.Result = new FileDecryptReturnVal(ATC_BROKEN_DATA, FilePath);
            return (false);
              }
              else
              {
            // not AttacheCase data
            e.Result = new FileDecryptReturnVal(NOT_ATC_DATA, FilePath);
            return(false);
              }

              Rfc2898DeriveBytes deriveBytes;
              if (PasswordBinary == null)
              {
            deriveBytes = new Rfc2898DeriveBytes(Password, _salt, 1000);
              }
              else
              {
            deriveBytes = new Rfc2898DeriveBytes(PasswordBinary, _salt, 1000);
              }

              byte[] key = deriveBytes.GetBytes(32);
              byte[] iv = deriveBytes.GetBytes(32);

              using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
              {
            if (fs.Length < 32)
            {
              // not AttacheCase data
              e.Result = new FileDecryptReturnVal(NOT_ATC_DATA, FilePath);
              return (false);
            }
            else
            {
              if (_ExeOutSize > 0)
              {
            // self-executable file
            fs.Seek(_ExeOutSize + 36, SeekOrigin.Begin);
              }
              else
              {
            fs.Seek(36, SeekOrigin.Begin);
              }
            }

            try
            {
              // The Header of MemoryStream is encrypted
              using (Rijndael aes = new RijndaelManaged())
              {
            aes.BlockSize = 256;             // BlockSize = 32 bytes
            aes.KeySize = 256;               // KeySize = 32 bytes
            aes.Mode = CipherMode.CBC;       // CBC mode
            aes.Padding = PaddingMode.Zeros; // Padding mode is "ZEROS".

            aes.Key = key;
            aes.IV = iv;

            // Decryption interface.
            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
            using (CryptoStream cse = new CryptoStream(fs, decryptor, CryptoStreamMode.Read))
            {
              using (MemoryStream ms = new MemoryStream())
              {
                byteArray = new byte[_AtcHeaderSize];
                len = cse.Read(byteArray, 0, _AtcHeaderSize);
                ms.Write(byteArray, 0, _AtcHeaderSize);
            #if (DEBUG)
                //string AppDirPath = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);
                string DesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
                string TempFilePath = Path.Combine(DesktopPath, "decrypt_header.txt");
                using (StreamWriter sw = new StreamWriter(TempFilePath, false, Encoding.UTF8))
                {
                  sw.Write(Encoding.UTF8.GetString(byteArray));
                }
            #endif
                // Check Password Token
                if (Encoding.UTF8.GetString(byteArray).IndexOf(AtC_ENCRYPTED_TOKEN) > -1)
                {
                  // Decryption is succeeded.
                }
                else
                {
                  // Token is not match ( Password is not correct )
                  e.Result = new FileDecryptReturnVal(PASSWORD_TOKEN_NOT_FOUND, FilePath);
                  return (false);
                }

                ms.Position = 0;

                var sr = new StreamReader(ms, Encoding.UTF8);
                string line;

                while ((line = sr.ReadLine()) != null)
                {
                  if (Regex.IsMatch(line, @"^[0-9]+:"))
                  {
                    FileList.Add(line);
                  }
                }

              }//end using (MemoryStream ms = new MemoryStream())

            }//end using (CryptoStream cse = new CryptoStream(fs, decryptor, CryptoStreamMode.Read));

              }//end using (Rijndael aes = new RijndaelManaged());

            }
            catch
            {
              e.Result = new FileDecryptReturnVal(ERROR_UNEXPECTED, "");
              return (false);
            }

              }//end using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read));

              //----------------------------------------------------------------------
              // Make a list array of the information for each file
              //----------------------------------------------------------------------
              _TotalFileSize = 0;
              string ParentFolder = "";
              bool fDirectoryTraversal = false;
              string InvalidFilePath = "";
              FileList.ForEach(delegate (string OutputLine)
              {
            int LastWriteDate, CreateDate;
            double LastWriteTime, CreateTime;
            DateTime LastWriteDateTime = DateTime.Parse("0001/01/01");
            DateTime CreationDateTime = DateTime.Parse("0001/01/01");

            FileListData fd = new FileListData();
            string[] OutputFileData = OutputLine.Split('\t');

            //-----------------------------------
            // File number
            //
            int FileNum;
            // e.g.)
            // 0:sample.txt[\t]49657[\t]32[\t]736194[\t]39585.875[\t]736194[\t]30186.782[\t]5f43aa1fed05350f34c2fabb7ed938457b2497f2b54a50415b51882f333b8ae1
            string[] FilePathSplits = OutputFileData[0].Split(':');
            if (Int32.TryParse(FilePathSplits[0], out FileNum) == false)
            {
              FileNum = -1;
            }
            //-----------------------------------
            // ディレクトリ・トラバーサル対策
            // Directory traversal countermeasures
            if (OutputFileData[0].IndexOf(@"..\") >= 0)
            {
              fDirectoryTraversal = true;
              InvalidFilePath = OutputFileData[0];
            }

            //-----------------------------------
            // Parent folder is not created.
            //
            if (_fNoParentFolder == true)
            {
              if (FileNum == 0)
              {
            if(FilePathSplits.Length > 2)  // ルートディレクトリ(ex. 0:G:\Test.txt)
            {
              ParentFolder = FilePathSplits[2];
            }
            else
            {
              ParentFolder = FilePathSplits[1];
            }
              }
              else
              {
            if (FilePathSplits.Length > 2)  // ルートディレクトリ
            {
              StringBuilder sb = new StringBuilder(FilePathSplits[2]);
              len = ParentFolder.Length;
              FilePathSplits[2] = sb.Replace(ParentFolder, "", 0, len).ToString();
            }
            else
            {
              StringBuilder sb = new StringBuilder(FilePathSplits[1]);
              len = ParentFolder.Length;
              FilePathSplits[1] = sb.Replace(ParentFolder, "", 0, len).ToString();
            }
              }
            }

            //-----------------------------------
            // File path
            //
            string OutFilePath = "";
            if (_fSalvageIntoSameDirectory == true) // Salvage mode?
            {
              OutFilePath = Path.Combine(OutDirPath, Path.GetFileName(FilePathSplits[1]));
            }
            else
            {
              if(FilePathSplits.Length > 2)
              {
            OutFilePath = Path.Combine(OutDirPath, FilePathSplits[2]);
              }
              else
              {
            OutFilePath = Path.Combine(OutDirPath, FilePathSplits[1]);
              }
            }
            fd.FilePath = OutFilePath;

            //-----------------------------------
            // File size
            if (Int64.TryParse(OutputFileData[1], out fd.FileSize) == false)
            {
              fd.FileSize = -1;
            }
            else
            {
              _TotalFileSize += fd.FileSize;
            }
            //-----------------------------------
            // File attribute
            if (Int32.TryParse(OutputFileData[2], out fd.FileAttribute) == false)
            {
              fd.FileAttribute = -1;
            }

            /*
                    * TTimeStamp = record
                    *  Time: Integer;      { Number of milliseconds since midnight }
                    *  Date: Integer;      { One plus number of days since 1/1/0001 }
                    * end;
                */
            //-----------------------------------
            // Last update timestamp
            if (_fSameTimeStamp == false && Int32.TryParse(OutputFileData[3], out LastWriteDate) == true)
            {
              LastWriteDateTime = LastWriteDateTime.AddDays(LastWriteDate); // Add days
            }
            else
            {
              LastWriteDateTime = DateTime.Now;
            }

            if (_fSameTimeStamp == false && Double.TryParse(OutputFileData[4], out LastWriteTime) == true)
            {
              LastWriteDateTime = LastWriteDateTime.AddSeconds(LastWriteTime);  // Add seconds
            }
            else
            {
              LastWriteDateTime = DateTime.Now;
            }

            fd.LastWriteDateTime = LastWriteDateTime;

            //-----------------------------------
            // Create datetime
            if (_fSameTimeStamp == false && Int32.TryParse(OutputFileData[5], out CreateDate) == true)
            {
              CreationDateTime = CreationDateTime.AddDays(CreateDate);
            }
            else
            {
              CreationDateTime = DateTime.Now;
            }

            if (_fSameTimeStamp == false && Double.TryParse(OutputFileData[6], out CreateTime) == true)
            {
              CreationDateTime = CreationDateTime.AddSeconds(CreateTime);
            }
            else
            {
              CreationDateTime = DateTime.Now;
            }

            fd.CreationDateTime = CreationDateTime;

            //-----------------------------------
            // SHA-256 hash
            if (OutputFileData.Length > 7)
            {
              fd.Hash = OutputFileData[7];
            }

            //-----------------------------------
            // Insert to 'Key-Value' type array data.
            dic.Add(FileNum, fd);

              });

              // Directory traversal countermeasures
              if (fDirectoryTraversal == true)
              {
            e.Result = new FileDecryptReturnVal(INVALID_FILE_PATH, InvalidFilePath);
            return(false);
              }

              //----------------------------------------------------------------------
              // Check the disk space
              //----------------------------------------------------------------------
              string RootDriveLetter = Path.GetPathRoot(OutDirPath).Substring(0, 1);

              if (RootDriveLetter == "\\")
              {
            // Network
              }
              else
              {
            DriveInfo drive = new DriveInfo(RootDriveLetter);

            DriveType driveType = drive.DriveType;
            switch (driveType)
            {
              case DriveType.CDRom:
              case DriveType.NoRootDirectory:
              case DriveType.Unknown:
            break;
              case DriveType.Fixed:     // Local Drive
              case DriveType.Network:   // Mapped Drive
              case DriveType.Ram:       // Ram Drive
              case DriveType.Removable: // Usually a USB Drive

            // The drive is not available, or not enough free space.
            if (drive.IsReady == false || drive.AvailableFreeSpace < _TotalFileSize)
            {
              e.Result = new FileDecryptReturnVal(NO_DISK_SPACE, drive.ToString(), _TotalFileSize, drive.AvailableFreeSpace);
              return (false);
            }
            break;
            }
              }

              //-----------------------------------
              // Decrypt file main data.
              //-----------------------------------
              try
              {
            using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
              //-----------------------------------
              // Adjust the header data in 32 bytes
              int mod = _AtcHeaderSize % 32;
              if (_fExecutableType == true)
              {
            fs.Seek(_ExeOutSize + 36 + _AtcHeaderSize + 32 - mod, SeekOrigin.Begin);
              }
              else
              {
            fs.Seek(36 + _AtcHeaderSize + 32 - mod, SeekOrigin.Begin);
              }

              //-----------------------------------
              // Decyption
              using (Rijndael aes = new RijndaelManaged())
              {
            aes.BlockSize = 256;             // BlockSize = 32bytes
            aes.KeySize = 256;               // KeySize = 32bytes
            aes.Mode = CipherMode.CBC;       // CBC mode
            aes.Padding = PaddingMode.Zeros; // Padding mode
            aes.Key = key;
            aes.IV = iv;
            #if (DEBUG)
            //System.Windows.Forms.MessageBox.Show("dic.Count: " + dic.Count);
            #endif
            //Decryption interface.
            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
            using (CryptoStream cse = new CryptoStream(fs, decryptor, CryptoStreamMode.Read))
            {
              using (Ionic.Zlib.DeflateStream ds = new Ionic.Zlib.DeflateStream(cse, Ionic.Zlib.CompressionMode.Decompress))
              {
                /*
                public struct FileListData
                {
                  public string FilePath;
                  public Int64 FileSize;
                  public int FileAttribute;
                  public DateTime LastWriteDateTime;
                  public DateTime CreationDateTime;
                  public string Sha256String;
                }
                */
                FileStream outfs = null;
                Int64 FileSize = 0;
                int FileIndex = 0;

                bool fSkip = false;

                if (_fNoParentFolder == true)
                {
                  if (dic[0].FilePath.EndsWith("\\") == true)
                  {
                    FileIndex = 1;  // Ignore parent folder.
                  }
                }

                //----------------------------------------------------------------------
                byteArray = new byte[BUFFER_SIZE];

                //while ((len = ds.Read(byteArray, 0, BUFFER_SIZE)) > 0)
                while(true)
                {
                  if (_AppVersion < 3013)
                  {
                    len = cse.Read(byteArray, 0, BUFFER_SIZE);
                  }
                  else
                  {
                    len = ds.Read(byteArray, 0, BUFFER_SIZE);
                  }

                  // 末尾の0バイトファイル、またはフォルダ生成対策
                  if (len == 0) len = 1;

                  int buffer_size = len;

                  while (len > 0)
                  {
                    //----------------------------------------------------------------------
                    // 書き込み中のファイルまたはフォルダが無い場合は作る
                    // Create them if there is no writing file or folder.
                    //----------------------------------------------------------------------
                    if (outfs == null)
                    {
                      //-----------------------------------
                      // Create file or dirctories.
                      if (dic.ContainsKey(FileIndex) == false)
                      {
                        if (FileIndex > dic.Count - 1)
                        {
                          e.Result = new FileDecryptReturnVal(DECRYPT_SUCCEEDED);
                          return (true);
                        }
                        else
                        {
                          e.Result = new FileDecryptReturnVal(FILE_INDEX_NOT_FOUND, FileIndex);
                          return (false);
                        }
                      }
                      else
                      {
                        //-----------------------------------
                        // Create directory
                        //-----------------------------------
                        if (dic[FileIndex].FilePath.EndsWith("\\") == true)
                        {
                          string path = Path.Combine(OutDirPath, dic[FileIndex].FilePath);
                          DirectoryInfo di = new DirectoryInfo(path);

                          // File already exists.
                          if (Directory.Exists(path) == true)
                          {
                            // Temporary option for overwriting
                            // private const int USER_CANCELED  = -1;
                            // private const int OVERWRITE      = 1;
                            // private const int OVERWRITE_ALL  = 2;
                            // private const int KEEP_NEWER     = 3;
                            // private const int KEEP_NEWER_ALL = 4;
                            // private const int SKIP           = 5;
                            // private const int SKIP_ALL       = 6;
                            if (_TempOverWriteOption == OVERWRITE_ALL)
                            {
                              // Overwrite ( New create )
                            }
                            else if (_TempOverWriteOption == SKIP_ALL)
                            {
                              fSkip = true;
                            }
                            else if (_TempOverWriteOption == KEEP_NEWER_ALL)
                            {
                              if (di.LastWriteTime > dic[FileIndex].LastWriteDateTime)
                              {
                                fSkip = true; // old directory
                              }
                            }
                            else
                            {
                              // Show dialog of comfirming to overwrite.
                              dialog(0, path);

                              // Cancel
                              if (_TempOverWriteOption == USER_CANCELED)
                              {
                                e.Result = new FileDecryptReturnVal(USER_CANCELED);
                                return (false);
                              }
                              else if (_TempOverWriteOption == OVERWRITE || _TempOverWriteOption == OVERWRITE_ALL)
                              {
                                // Overwrite ( New create )
                              }
                              // Skip, or Skip All
                              else if (_TempOverWriteOption == SKIP_ALL)
                              {
                                fSkip = true;
                                e.Result = new FileDecryptReturnVal(DECRYPT_SUCCEEDED);
                                return (true);
                              }
                              else if (_TempOverWriteOption == SKIP)
                              {
                                fSkip = true;
                              }
                              else if (_TempOverWriteOption == KEEP_NEWER || _TempOverWriteOption == KEEP_NEWER_ALL)
                              { // New file?
                                if (di.LastWriteTime > dic[FileIndex].LastWriteDateTime)
                                {
                                  fSkip = true;
                                }
                              }
                            }

                            if ( fSkip == false)
                            {
                              //隠し属性を削除する
                              di.Attributes &= ~FileAttributes.Hidden;
                              //読み取り専用を削除
                              di.Attributes &= ~FileAttributes.ReadOnly;
                            }

                            //すべての属性を解除
                            //File.SetAttributes(path, FileAttributes.Normal);

                          } // end if ( Directory.Exists )

                          Directory.CreateDirectory(dic[FileIndex].FilePath);
                          _OutputFileList.Add(dic[FileIndex].FilePath);
                          FileSize = 0;
                          FileIndex++;

                          if (FileIndex > dic.Count - 1)
                          {
                            e.Result = new FileDecryptReturnVal(DECRYPT_SUCCEEDED);
                            return (true);
                          }

                          continue;

                        }
                        //-----------------------------------
                        // Create file
                        //-----------------------------------
                        else
                        {
                          string path = Path.Combine(OutDirPath, dic[FileIndex].FilePath);
                          FileInfo fi = new FileInfo(path);

                          // File already exists.
                          if (File.Exists(path) == true)
                          {
                            // Salvage Data Mode
                            if (_fSalvageIntoSameDirectory == true)
                            {
                              int SerialNum = 0;
                              while (File.Exists(path) == true)
                              {
                                path = getFileNameWithSerialNumber(path, SerialNum);
                                SerialNum++;
                              }
                            }
                            else
                            {
                              // Temporary option for overwriting
                              // private const int USER_CANCELED  = -1;
                              // private const int OVERWRITE      = 1;
                              // private const int OVERWRITE_ALL  = 2;
                              // private const int KEEP_NEWER     = 3;
                              // private const int KEEP_NEWER_ALL = 4;
                              // private const int SKIP           = 5;
                              // private const int SKIP_ALL       = 6;
                              if (_TempOverWriteOption == OVERWRITE_ALL)
                              {
                                // Overwrite ( New create )
                              }
                              else if (_TempOverWriteOption == SKIP_ALL)
                              {
                                fSkip = true;
                              }
                              else if (_TempOverWriteOption == KEEP_NEWER_ALL)
                              {
                                if (fi.LastWriteTime > dic[FileIndex].LastWriteDateTime)
                                {
                                  fSkip = true;
                                }
                              }
                              else
                              {
                                // Show dialog of comfirming to overwrite.
                                dialog(0, path);

                                // Cancel
                                if (_TempOverWriteOption == USER_CANCELED)
                                {
                                  e.Result = new FileDecryptReturnVal(USER_CANCELED);
                                  return (false);
                                }
                                else if (_TempOverWriteOption == OVERWRITE || _TempOverWriteOption == OVERWRITE_ALL)
                                {
                                  // Overwrite ( New create )
                                }
                                // Skip, or Skip All
                                else if (_TempOverWriteOption == SKIP || _TempOverWriteOption == SKIP_ALL)
                                {
                                  fSkip = true;
                                }
                                else if (_TempOverWriteOption == KEEP_NEWER || _TempOverWriteOption == KEEP_NEWER_ALL)
                                { // New file?
                                  if (fi.LastWriteTime > dic[FileIndex].LastWriteDateTime)
                                  {
                                    fSkip = true; // old directory
                                  }
                                }
                              }

                              if (fSkip == false)
                              {
                                //隠し属性を削除する
                                //fi.Attributes &= ~FileAttributes.Hidden;
                                //読み取り専用を削除
                                //fi.Attributes &= ~FileAttributes.ReadOnly;

                                //すべての属性を解除
                                File.SetAttributes(path, FileAttributes.Normal);

                              }

                            }

                          }// end if ( File.Exists );

                          // Salvage data mode
                          // サルベージ・モード
                          if (_fSalvageToCreateParentFolderOneByOne == true)
                          {
                            // Decrypt one by one while creating the parent folder.
                            Directory.CreateDirectory(Path.GetDirectoryName(path));
                          }

                          if ( fSkip == true)
                          {
                            // Not create file
                          }
                          else
                          {
                            outfs = new FileStream(path, FileMode.Create, FileAccess.Write);
                          }

                          _OutputFileList.Add(path);
                          FileSize = 0;

                        }

                      }

                    }// end if (outfs == null);

                    //----------------------------------------------------------------------
                    // Write data
                    //----------------------------------------------------------------------
                    if (FileSize + len < (Int64)dic[FileIndex].FileSize)
                    {
                      if (outfs != null || fSkip == true)
                      {
                        // まだまだ書き込める
                        // can write more
                        if (fSkip == false)
                        {
                          outfs.Write(byteArray, buffer_size - len, len);
                        }
                        FileSize += len;
                        _TotalSize += len;
                        len = 0;
                      }
                    }
                    else
                    {
                      // ファイルの境界を超えて読み込んでいる
                      // Reading beyond file boundaries
                      int rest = (int)(dic[FileIndex].FileSize - FileSize);

                      if (fSkip == false)
                      {
                        // 書き込み完了
                        // Write completed
                        outfs.Write(byteArray, buffer_size - len, rest);
                      }

                      _TotalSize += rest;

                      len -= rest;

                      if (outfs != null)
                      {
                        // 生成したファイルを閉じる
                        // File close
                        outfs.Close();
                        outfs = null;
                      }

                      //----------------------------------------------------------------------
                      // ファイル属性の復元
                      // Restore file attributes

                      if (fSkip == false)
                      {
                        FileInfo fi = new FileInfo(dic[FileIndex].FilePath);
                        // タイムスタンプの復元
                        // Restore the timestamp of a file
                        fi.CreationTime = (DateTime)dic[FileIndex].CreationDateTime;
                        fi.LastWriteTime = (DateTime)dic[FileIndex].LastWriteDateTime;
                        // ファイル属性の復元
                        // Restore file attribute.
                        fi.Attributes = (FileAttributes)dic[FileIndex].FileAttribute;

                        // ハッシュ値のチェック
                        // Check the hash of a file
                        string hash = GetSha256HashFromFile(dic[FileIndex].FilePath);
                        if (hash != dic[FileIndex].Hash.ToString())
                        {
                          e.Result = new FileDecryptReturnVal(NOT_CORRECT_HASH_VALUE, dic[FileIndex].FilePath);
                          return (false);
                        }
                      }

                      FileSize = 0;
                      FileIndex++;

                      fSkip = false;

                      if (FileIndex > dic.Count - 1)
                      {
                        e.Result = new FileDecryptReturnVal(DECRYPT_SUCCEEDED);
                        return (true);
                      }

                    }
                    //----------------------------------------------------------------------
                    //進捗の表示
                    string MessageText = "";
                    if (_TotalNumberOfFiles > 1)
                    {
                      MessageText = FilePath + " ( " + _NumberOfFiles.ToString() + "/" + _TotalNumberOfFiles.ToString() + " files" + " )";
                    }
                    else
                    {
                      MessageText = FilePath;
                    }

                    MessageList = new ArrayList();
                    MessageList.Add(DECRYPTING);
                    MessageList.Add(MessageText);
                    float percent = ((float)_TotalSize / _TotalFileSize);
                    worker.ReportProgress((int)(percent * 10000), MessageList);

                    // User cancel
                    if (worker.CancellationPending == true)
                    {
                      if (outfs != null)
                      {
                        outfs.Close();
                        outfs = null;
                      }
                      e.Cancel = true;
                      return (false);
                    }

                  }// end while(len > 0);

                }// end while ((len = ds.Read(byteArray, 0, BUFFER_SIZE)) > 0);

              }// end using (DeflateStream ds = new DeflateStream(cse, CompressionMode.Decompress));

            }// end using (CryptoStream cse = new CryptoStream(fs, decryptor, CryptoStreamMode.Read));

              }// end using (Rijndael aes = new RijndaelManaged());

            }// end using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read));

              }
              catch (Exception ex)
              {
            #if (DEBUG)
            System.Windows.Forms.MessageBox.Show("Exception!");
            #endif

            System.Windows.Forms.MessageBox.Show(ex.Message);

            e.Result = new FileDecryptReturnVal(ERROR_UNEXPECTED);
            return (false);

              }

              e.Result = new FileDecryptReturnVal(DECRYPT_SUCCEEDED);
              return (true);
        }
 public DeflateHttpContent(Stream stream)
 {
     m_stream = new Ionic.Zlib.DeflateStream(stream, Ionic.Zlib.CompressionMode.Decompress);
 }
Ejemplo n.º 15
0
        /// <summary>
        /// Multiple files or directories is encrypted by AES (exactly Rijndael) to use password string.
        /// 複数のファイル、またはディレクトリをAES(正確にはRijndael)を使って指定のパスワードで暗号化する
        /// </summary>
        /// <param name="FilePath">File path or directory path is encrypted</param>
        /// <param name="OutFilePath">Output encryption file name</param>
        /// <param name="Password">Encription password string</param>
        /// <returns>Encryption success(true) or failed(false)</returns>
        public Tuple<bool, int> Encrypt(
			object sender, DoWorkEventArgs e, 
			string[] FilePaths, string OutFilePath, 
			string Password, byte[] PasswordBinary,
			string NewArchiveName)
        {
            byte[] bufferPassword;
            byte[] bufferKey = new byte[32];

              _AtcFilePath = OutFilePath;

              BackgroundWorker worker = sender as BackgroundWorker;

              //-----------------------------------
              // Header data is starting.
              // Progress event handler
              ArrayList MessageList = new ArrayList();
              MessageList.Add(READY_FOR_ENCRYPT);
              MessageList.Add(Path.GetFileName(OutFilePath));
              worker.ReportProgress(0, MessageList);

              _FileList = new List<string>();
            byte[] byteArray = null;

            using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write))
              {
            // 自己実行形式ファイル(Self-executable file)
            if (_fExecutable == true)
            {
              ExeOutFileSize = rawData.Length;
              outfs.Write(rawData, 0, (int)ExeOutFileSize);
            }

            _StartPos = outfs.Seek(0, SeekOrigin.End);

            byteArray = new byte[16];
            // Plain text header
            byteArray = BitConverter.GetBytes(DATA_SUB_VERSION);
            outfs.Write(byteArray, 0, 1);
                byteArray = null;
            byteArray = BitConverter.GetBytes(RESERVED_DATA);
            outfs.Write(byteArray, 0, 1);
                byteArray = null;
            byteArray = BitConverter.GetBytes(charMissTypeLimits);
            outfs.Write(byteArray, 0, 1);
                byteArray = null;
                byteArray = BitConverter.GetBytes(fBrocken);
            outfs.Write(byteArray, 0, 1);
                byteArray = null;
                byteArray =Encoding.ASCII.GetBytes(STRING_TOKEN_NORMAL);
            outfs.Write(byteArray, 0, 16);

                byteArray = null;
                byteArray = BitConverter.GetBytes(DATA_FILE_VERSION);
            outfs.Write(byteArray, 0, 4);
                byteArray = null;
                byteArray = BitConverter.GetBytes(TYPE_ALGORISM);
            outfs.Write(byteArray, 0, 4);

            // Reserve cipher text header size after encrypting.
                byteArray = null;
            byteArray = BitConverter.GetBytes(_AtcHeaderSize);
            outfs.Write(byteArray, 0, 4);

            // Cipher text header.
            using (MemoryStream ms = new MemoryStream())
            {
                    byteArray =Encoding.ASCII.GetBytes("Passcode:AttacheCase\n");
                    ms.Write(byteArray, 0, byteArray.Length);

                    DateTime dt = DateTime.Now;
                    byteArray = Encoding.ASCII.GetBytes("LastDateTime:" + dt.ToString("yyyy/MM/dd HH:mm:ss\n"));
                    ms.Write(byteArray, 0, byteArray.Length);

                    int FileNumber = 0;
                    string ParentPath;
                    ArrayList FileInfoList = new ArrayList();

                    //----------------------------------------------------------------------
                    // Put together files in one ( Save as the name ).
                    // 複数ファイルを一つにまとめる(ファイルに名前をつけて保存)
                    if (NewArchiveName != "")
                    {
                        // Now time
                        DateTime dtNow = new DateTime();
                        FileInfoList.Add("Fn_0:" +                            // File number
                                           NewArchiveName + "\\\t" +            // File name
                                                         "0"  + "\t" +                        // File size
                                                         "16" + "\t" +                        // File attribute
                                                         dtNow.Date.Subtract(new DateTime(1, 1, 1)).TotalDays + "\t" +  // Last write date
                                                         dtNow.TimeOfDay.TotalSeconds + "\t" + // Last write time
                                                         dtNow.Date.Subtract(new DateTime(1, 1, 1)).TotalDays + "\t" +  // Creation date
                                                         dtNow.TimeOfDay.TotalSeconds);       // Creation time
                        FileNumber++;
                    }

                    //----------------------------------------------------------------------
                    // When encrypt multiple files
                    // 複数のファイルを暗号化する場合
                    foreach (string FilePath in FilePaths)
                    {
                        ParentPath = Path.GetDirectoryName(FilePath) + "\\";

                        if ((worker.CancellationPending == true))
                        {
                            e.Cancel = true;
                            return Tuple.Create(false, USER_CANCELED);
                        }

                        //----------------------------------------------------------------------
                        // 暗号化リストを生成(ファイル)
                        // Create file to encrypt list ( File )
                        //----------------------------------------------------------------------
                        if (File.Exists(FilePath) == true)
                        {
                            ArrayList Item = GetFileInfo(ParentPath, FilePath);
                            FileInfoList.Add("Fn_" + FileNumber.ToString() + ":" + // File number
                                                //Item[0] + "\t" +                      // TypeFlag ( Directory: 0, file: 1 )
                                                //Item[1] + "\t" +                      // Absolute file path
                                                                Item[2] + "\t" +                      // Relative file path
                                                                Item[3].ToString() + "\t" +           // File size
                                                                Item[4].ToString() + "\t" +           // File attribute
                                                                Item[5].ToString() + "\t" +           // Last write date
                                                                Item[6].ToString() + "\t" +           // Last write time
                                                                Item[7].ToString() + "\t" +           // Creation date
                                                                Item[8].ToString());                  // Creation time

                            // files only
                            if (Convert.ToInt32(Item[0]) == 1)
                            {
                                // Files list for encryption
                                _FileList.Add(Item[1].ToString());	// Absolute file path
                                // Total file size
                                _TotalFileSize += Convert.ToInt64(Item[3]);
                            }

                            FileNumber++;

                        }
                        //----------------------------------------------------------------------
                        // 暗号化リストを生成(ディレクトリ)
                        // Create file to encrypt list ( Directory )
                        //----------------------------------------------------------------------
                        else
                        {
              // Directory
              _FileList.Add(FilePath);  // Absolute file path

              foreach (ArrayList Item in GetFileList(ParentPath, FilePath))
                            {
                                if ((worker.CancellationPending == true))
                                {
                                    e.Cancel = true;
                                    return Tuple.Create(false, USER_CANCELED);
                                }

                                if (NewArchiveName != "")
                                {
                                    Item[2] = NewArchiveName + "\\" + Item[2];
                                }

                                FileInfoList.Add("Fn_" + FileNumber.ToString() + ":" + // File number
                                                    //Item[0] + "\t" +                      // TypeFlag ( Directory: 0, file: 1 )
                                                    //Item[1] + "\t" +                      // Absolute file path
                                                                    Item[2] + "\t" +                    // Relative file path
                                                                    Item[3].ToString() + "\t" +           // File size
                                                                    Item[4].ToString() + "\t" +           // File attribute
                                                                    Item[5].ToString() + "\t" +           // Last write date
                                                                    Item[6].ToString() + "\t" +           // Last write time
                                                                    Item[7].ToString() + "\t" +           // Creation date
                                                                    Item[8].ToString());                  // Creation time

                                if (Convert.ToInt32(Item[0]) == 1)
                { // files only
                  // Files list for encryption
                  _FileList.Add(Item[1].ToString());	// Absolute file path
                                    // Total file size
                                    _TotalFileSize += Convert.ToInt64(Item[3]);
                                }
                else
                { // Directory
                  _FileList.Add(Item[1].ToString());	// Absolute file path
                }

                FileNumber++;

                            }// end foreach (ArrayList Item in GetFilesList(ParentPath, FilePath));

                        }

                    }// end foreach (string FilePath in FilePaths);

              //----------------------------------------------------------------------
              // Check the disk space
              //----------------------------------------------------------------------
              string RootDriveLetter = Path.GetPathRoot(OutFilePath).Substring(0, 1);

              if (RootDriveLetter == "\\")
              {
            // Network
              }
              else
              {
            DriveInfo drive = new DriveInfo(RootDriveLetter);

            DriveType driveType = drive.DriveType;
            switch (driveType)
            {
              case DriveType.CDRom:
              case DriveType.NoRootDirectory:
              case DriveType.Unknown:
                break;
              case DriveType.Fixed:     // Local Drive
              case DriveType.Network:   // Mapped Drive
              case DriveType.Ram:       // Ram Drive
              case DriveType.Removable: // Usually a USB Drive

                // The drive is not available, or not enough free space.
                if (drive.IsReady == false || drive.AvailableFreeSpace < _TotalFileSize)
                {
                  e.Result = NO_DISK_SPACE;
                  // not available free space
                  return Tuple.Create(false, NO_DISK_SPACE);
                }
                break;
            }
              }

              //----------------------------------------------------------------------
              // Create header data

              string[] FileInfoText = (string[])FileInfoList.ToArray(typeof(string));

                    // Shift-JIS ( Japanese )
              byteArray = Encoding.GetEncoding(932).GetBytes(string.Join("\n", FileInfoText));
              ms.Write(byteArray, 0, byteArray.Length);
                    Console.WriteLine(FileInfoText);
              // UTF-8
              byteArray = Encoding.UTF8.GetBytes("\n"+string.Join("\n", FileInfoText).Replace("Fn_", "U_"));
              ms.Write(byteArray, 0, byteArray.Length);
                    Console.WriteLine(FileInfoText);

            #if (DEBUG)
              //Output text file of header contents for debug.
              Int64 NowPosition = ms.Position;
              ms.Position = 0;
                    //Save to Desktop folder.
                    string DesktopPath = System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
                    string HeaderTextFilePath = Path.Combine(DesktopPath, "encrypt_header.txt");
              FileStream fsDebug = new FileStream(HeaderTextFilePath, FileMode.Create, FileAccess.Write);
              ms.WriteTo(fsDebug);
              fsDebug.Close();
              ms.Position = NowPosition;
            #endif
                // The Header of MemoryStream is encrypted
              using (Rijndael aes = new RijndaelManaged())
              {
            aes.BlockSize = 256;              // BlockSize = 16bytes
            aes.KeySize = 256;                // KeySize = 16bytes
            aes.Mode = CipherMode.CBC;        // CBC mode
            //aes.Padding = PaddingMode.Zeros;  // Padding mode is "None".

                        // Password
                        if (PasswordBinary != null)
                        {	// Binary
                            bufferPassword = PasswordBinary;
                        }
                        else
                        {	// Text
                            bufferPassword = Encoding.UTF8.GetBytes(Password);
                            //byte[] bufferPassword = Encoding.GetEncoding(932).GetBytes(Password);  // Shift-JIS
                        }

                        // Password is 256 bit, so truncated up to 32 bytes or fill up the data size.
                        // パスワードは256 bitなので、32バイトまで切り詰めるか、あるいはそのサイズまで埋める処理
                        for (int i = 0; i < bufferKey.Length; i++)
                        {
                            if (i < bufferPassword.Length)
                            {
                                // Cut down to 32 bytes characters.
                                bufferKey[i] = bufferPassword[i];
                            }
                            else
                            {
                                bufferKey[i] = 0;	// Zero filled
                            }
                        }
            aes.Key = bufferKey;

                        // Initilization Vector
                        aes.GenerateIV();
                        outfs.Write(aes.IV, 0, 32);

                        ms.Position = 0;
                        //Encryption interface.
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
            using (CryptoStream cse = new CryptoStream(outfs, encryptor, CryptoStreamMode.Write))
            {
                            //----------------------------------------------------------------------
                            // ヘッダーの暗号化
                            //----------------------------------------------------------------------
                            int len = 0;
                            _AtcHeaderSize = 0;		// exclude IV of header
              buffer = new byte[BUFFER_SIZE];
              while ((len = ms.Read(buffer, 0, BUFFER_SIZE)) > 0)
              {
                                cse.Write(buffer, 0, len);
                _AtcHeaderSize += len;
              }
                        }

                    }// end using (Rijndael aes = new RijndaelManaged());

                }// end  using (MemoryStream ms = new MemoryStream());

            }// end using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write));

            //----------------------------------------------------------------------
            // 本体データの暗号化
            //----------------------------------------------------------------------
            using (FileStream outfs = new FileStream(OutFilePath, FileMode.OpenOrCreate, FileAccess.Write))
            {
                byteArray = new byte[4];
            // Back to current positon of 'encrypted file size'
            if (_fExecutable == true)
            {
                    outfs.Seek(ExeOutFileSize + 28, SeekOrigin.Begin);	// self executable file
                }
                else
                {
                    outfs.Seek(28, SeekOrigin.Begin);
                }

                byteArray = BitConverter.GetBytes(_AtcHeaderSize);
                outfs.Write(byteArray, 0, 4);

                // Out file stream postion move to end
                outfs.Seek(0, SeekOrigin.End);

                // The Header of MemoryStream is encrypted
                using (Rijndael aes = new RijndaelManaged())
                {
                    aes.BlockSize = 256;              // BlockSize = 16bytes
                    aes.KeySize = 256;                // KeySize = 16bytes
                    aes.Mode = CipherMode.CBC;        // CBC mode
              //aes.Padding = PaddingMode.PKCS7;  // Padding mode is "PKCS7".

              // Password is 256 bit, so truncated up to 32 bytes or fill up the data size.
              for (int i = 0; i < bufferKey.Length; i++)
                    {
                        if (i < bufferPassword.Length)
                        {
                            //Cut down to 32bytes characters.
                            bufferKey[i] = bufferPassword[i];
                        }
                        else
                        {
                            bufferKey[i] = 0;
                        }
                    }
                    aes.Key = bufferKey;
                    // Initilization Vector
                    byte[] iv = new byte[32];
                    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
                    rng.GetNonZeroBytes(iv);
                    aes.IV = iv;

                    outfs.Write(iv, 0, 32);

                    // Encryption interface.
                    ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
                    using (CryptoStream cse = new CryptoStream(outfs, encryptor, CryptoStreamMode.Write))
                    {
                        // zlib 2bytes header
                        cse.WriteByte(0x78);

            // cse.WriteByte(0x01);	//No Compression/low
            cse.WriteByte(0x9C);  //Default Compression
            //cse.WriteByte(0xDA);	 //Best Compression

            Ionic.Zlib.CompressionLevel flv = Ionic.Zlib.CompressionLevel.Default;
            switch (AppSettings.Instance.CompressRate)
            {
              case 0:
                flv = Ionic.Zlib.CompressionLevel.Level0;
                break;
              case 1:
                flv = Ionic.Zlib.CompressionLevel.Level1;
                break;
              case 2:
                flv = Ionic.Zlib.CompressionLevel.Level2;
                break;
              case 3:
                flv = Ionic.Zlib.CompressionLevel.Level3;
                break;
              case 4:
                flv = Ionic.Zlib.CompressionLevel.Level4;
                break;
              case 5:
                flv = Ionic.Zlib.CompressionLevel.Level5;
                break;
              case 6:
                flv = Ionic.Zlib.CompressionLevel.Level6;
                break;
              case 7:
                flv = Ionic.Zlib.CompressionLevel.Level7;
                break;
              case 8:
                flv = Ionic.Zlib.CompressionLevel.Level8;
                break;
              case 9:
                flv = Ionic.Zlib.CompressionLevel.Level9;
                break;
            }

            using ( Ionic.Zlib.DeflateStream ds = new Ionic.Zlib.DeflateStream(cse, Ionic.Zlib.CompressionMode.Compress, flv))
                        {
                            int len = 0;
                            foreach (string path in _FileList)
                            {
                                // Only file is encrypted
                                if (File.Exists(path) == true)
                                {
                                    buffer = new byte[BUFFER_SIZE];
                                    using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
                                    {
                                        len = 0;
                                        while ((len = fs.Read(buffer, 0, BUFFER_SIZE)) > 0)
                                        {
                                            ds.Write(buffer, 0, len);
                                            _TotalSize += len;

                                            string MessageText = "";
                                            if (_TotalNumberOfFiles > 1)
                                            {
                                                MessageText = path + " ( " + _NumberOfFiles.ToString() + " files/ " + _TotalNumberOfFiles.ToString() + " folders )";
                                            }
                                            else
                                            {
                                                MessageText = path;
                                            }

                      MessageList = new ArrayList();
                      MessageList.Add(DECRYPTING);
                      MessageList.Add(MessageText);
                      float percent = ((float)_TotalSize / _TotalFileSize);
                      worker.ReportProgress((int)(percent * 10000), MessageList);

                      if (worker.CancellationPending == true)
                                            {
                                                e.Cancel = true;
                                                return Tuple.Create(false, USER_CANCELED);
                                            }

                                        }
                                    }

                                } // end if (File.Exists(path) == true);

                            } // end foreach (string path in _FileList);

              /*
              Random r = new Random();
              byteArray = new byte[BUFFER_SIZE];
              r.NextBytes(byteArray);
              ds.Write(buffer, 0, BUFFER_SIZE);
              */

            } // end using ( Ionic.Zlib.DeflateStream ds);

              } // end using (CryptoStream cse);

                } // end using (Rijndael aes = new RijndaelManaged());

              } // end using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write));

              // Self-executable file
              if (fExecutable == true)
              {
            using (FileStream outfs = new FileStream(OutFilePath, FileMode.Open, FileAccess.Write))
            {
              Int64 DataSize = outfs.Seek(0, SeekOrigin.End);
              DataSize = DataSize - _StartPos;
              byteArray = BitConverter.GetBytes(DataSize);
              outfs.Write(byteArray, 0, sizeof(Int64));
            }
              }

              // Set the timestamp of encryption file to original files or directories
              if (_fKeepTimeStamp == true)
              {
            DateTime dtCreate = File.GetCreationTime((string)AppSettings.Instance.FileList[0]);
            DateTime dtUpdate = File.GetLastWriteTime((string)AppSettings.Instance.FileList[0]);
            DateTime dtAccess = File.GetLastAccessTime((string)AppSettings.Instance.FileList[0]);
            File.SetCreationTime(OutFilePath, dtCreate);
            File.SetLastWriteTime(OutFilePath, dtUpdate);
            File.SetLastAccessTime(OutFilePath, dtAccess);
              }

              //Encryption succeed.
              e.Result = ENCRYPT_SUCCEEDED;
              return Tuple.Create(true, ENCRYPT_SUCCEEDED);
        }
Ejemplo n.º 16
0
        private Stream MaybeApplyCompression(Stream s, long streamLength)
        {
            if (_CompressionMethod == 0x08 && CompressionLevel != Ionic.Zlib.CompressionLevel.None)
            {
                var o = new Ionic.Zlib.DeflateStream(s, Ionic.Zlib.CompressionMode.Compress,
                                                     CompressionLevel,
                                                     true);
                if (_container.CodecBufferSize > 0)
                    o.BufferSize = _container.CodecBufferSize;
                o.Strategy = _container.Strategy;
                return o;
            }


#if BZIP
            if (_CompressionMethod == 0x0c)
            {
#if !NETCF
                if (_container.ParallelDeflateThreshold == 0L ||
                    (streamLength > _container.ParallelDeflateThreshold &&
                     _container.ParallelDeflateThreshold > 0L))
                {

                    var o1 = new Ionic.BZip2.ParallelBZip2OutputStream(s, true);
                    return o1;
                }
#endif
                var o = new Ionic.BZip2.BZip2OutputStream(s, true);
                return o;
            }
#endif

            return s;
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Multiple files or directories is encrypted by AES (exactly Rijndael) to use password string.
        /// 複数のファイル、またはディレクトリをAES(正確にはRijndael)を使って指定のパスワードで暗号化する
        /// </summary>
        /// <param name="FilePath">File path or directory path is encrypted</param>
        /// <param name="OutFilePath">Output encryption file name</param>
        /// <param name="Password">Encription password string</param>
        /// <returns>Encryption success(true) or failed(false)</returns>
        public Tuple<bool, int> Encrypt(
      object sender, DoWorkEventArgs e,
      string[] FilePaths, string OutFilePath,
      string Password, byte[] PasswordBinary,
      string NewArchiveName)
        {
            _AtcFilePath = OutFilePath;

              BackgroundWorker worker = sender as BackgroundWorker;

              // The timestamp of original file
              DateTime dtCreate = File.GetCreationTime(FilePaths[0]);
              DateTime dtUpdate = File.GetLastWriteTime(FilePaths[0]);
              DateTime dtAccess = File.GetLastAccessTime(FilePaths[0]);

              // Create Header data.
              ArrayList MessageList = new ArrayList();
              MessageList.Add(READY_FOR_ENCRYPT);
              MessageList.Add(Path.GetFileName(OutFilePath));
              worker.ReportProgress(0, MessageList);

              _FileList = new List<string>();
              byte[] byteArray = null;

              // Salt
              Rfc2898DeriveBytes deriveBytes;
              if(PasswordBinary == null)
              { // String Password
            deriveBytes = new Rfc2898DeriveBytes(Password, 8, 1000);
              }
              else
              { // Binary Password
            byte[] random_salt = new byte[8];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(random_salt);
            deriveBytes = new Rfc2898DeriveBytes(PasswordBinary, random_salt, 1000);
              }
              byte[] salt = deriveBytes.Salt;
              byte[] key = deriveBytes.GetBytes(32);
              byte[] iv = deriveBytes.GetBytes(32);

              using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write))
              {
            // 自己実行形式ファイル(Self-executable file)
            if (_fExecutable == true)
            {
              ExeOutFileSize = rawData.Length;
              outfs.Write(rawData, 0, (int)ExeOutFileSize);
            }

            _StartPos = outfs.Seek(0, SeekOrigin.End);

            // Application version
            Version ver = ApplicationInfo.Version;
            short vernum = Int16.Parse(ver.ToString().Replace(".", ""));
            byteArray = BitConverter.GetBytes(vernum);
            outfs.Write(byteArray, 0, 2);
            // Input password limit
            byteArray = BitConverter.GetBytes(_MissTypeLimits);
            outfs.Write(byteArray, 0, 1);
            // Exceed the password input limit, destroy the file?
            byteArray = BitConverter.GetBytes(fBrocken);
            outfs.Write(byteArray, 0, 1);
            // Token that this is the AttacheCase file
            byteArray = Encoding.ASCII.GetBytes(STRING_TOKEN_NORMAL);
            outfs.Write(byteArray, 0, 16);
            // File sub version
            byteArray = BitConverter.GetBytes(DATA_FILE_VERSION);
            outfs.Write(byteArray, 0, 4);
            // The size of encrypted Atc header size ( reserved )
            byteArray = BitConverter.GetBytes((int)0);
            outfs.Write(byteArray, 0, 4);
            // Salt
            outfs.Write(salt, 0, 8);

            // Cipher text header.
            using (MemoryStream ms = new MemoryStream())
            {
              byteArray = Encoding.ASCII.GetBytes(AtC_ENCRYPTED_TOKEN + "\n");
              ms.Write(byteArray, 0, byteArray.Length);

              int FileNumber = 0;
              string ParentPath;
              ArrayList FileInfoList = new ArrayList();

              //----------------------------------------------------------------------
              // Put together files in one ( Save as the name ).
              // 複数ファイルを一つにまとめる(ファイルに名前をつけて保存)
              if (NewArchiveName != "")
              {
            // Now time
            DateTime dtNow = new DateTime();
            FileInfoList.Add("0:" +                              // File number
                             NewArchiveName + "\\\t" +           // File name
                             "0" + "\t" +                        // File size
                             "16" + "\t" +                       // File attribute
                             dtNow.Date.Subtract(new DateTime(1, 1, 1)).TotalDays + "\t" +  // Last write date
                             dtNow.TimeOfDay.TotalSeconds + "\t" + // Last write time
                             dtNow.Date.Subtract(new DateTime(1, 1, 1)).TotalDays + "\t" +  // Creation date
                             dtNow.TimeOfDay.TotalSeconds);       // Creation time
            FileNumber++;
              }

              //----------------------------------------------------------------------
              // When encrypt multiple files
              // 複数のファイルを暗号化する場合
              foreach (string FilePath in FilePaths)
              {
            ParentPath = Path.GetDirectoryName(FilePath);

            if(ParentPath.EndsWith("\\") == false)  // In case of 'C:\\' root direcroy.
            {
              ParentPath = ParentPath + "\\";
            }

            if ((worker.CancellationPending == true))
            {
              e.Cancel = true;
              return Tuple.Create(false, USER_CANCELED);
            }

            //----------------------------------------------------------------------
            // 暗号化リストを生成(ファイル)
            // Create file to encrypt list ( File )
            //----------------------------------------------------------------------
            if (File.Exists(FilePath) == true)
            {
              ArrayList Item = GetFileInfo(ParentPath, FilePath);
              FileInfoList.Add(FileNumber.ToString() + ":" + // File number
                                //Item[0] + "\t" +           // TypeFlag ( Directory: 0, file: 1 )
                                //Item[1] + "\t" +           // Absolute file path
                                Item[2] + "\t" +             // Relative file path
                                Item[3].ToString() + "\t" +  // File size
                                Item[4].ToString() + "\t" +  // File attribute
                                Item[5].ToString() + "\t" +  // Last write date
                                Item[6].ToString() + "\t" +  // Last write time
                                Item[7].ToString() + "\t" +  // Creation date
                                Item[8].ToString() + "\t" +  // Creation time
                                Item[9].ToString());         // SHA-256 Hash string

              // files only
              if (Convert.ToInt32(Item[0]) == 1)
              {
                // Files list for encryption
                _FileList.Add(Item[1].ToString());  // Absolute file path
                                                    // Total file size
                _TotalFileSize += Convert.ToInt64(Item[3]);
              }

              FileNumber++;

            }
            //----------------------------------------------------------------------
            // 暗号化リストを生成(ディレクトリ)
            // Create file to encrypt list ( Directory )
            //----------------------------------------------------------------------
            else
            {
              // Directory
              _FileList.Add(FilePath);  // Absolute file path

              foreach (ArrayList Item in GetFileList(ParentPath, FilePath))
              {
                if ((worker.CancellationPending == true))
                {
                  e.Cancel = true;
                  return Tuple.Create(false, USER_CANCELED);
                }

                if (NewArchiveName != "")
                {
                  Item[2] = NewArchiveName + "\\" + Item[2];
                }

                if ((int)Item[0] == 0)
                { // Directory
                  FileInfoList.Add(FileNumber.ToString() + ":" + // File number
                                    Item[2] + "\t" +             // Relative file path
                                    Item[3].ToString() + "\t" +  // File size
                                    Item[4].ToString() + "\t" +  // File attribute
                                    Item[5].ToString() + "\t" +  // Last write date
                                    Item[6].ToString() + "\t" +  // Last write time
                                    Item[7].ToString() + "\t" +  // Creation date
                                    Item[8].ToString());         // Creation time
                }
                else
                { // File
                  FileInfoList.Add(FileNumber.ToString() + ":" + // File number
                                    Item[2] + "\t" +             // Relative file path
                                    Item[3].ToString() + "\t" +  // File size
                                    Item[4].ToString() + "\t" +  // File attribute
                                    Item[5].ToString() + "\t" +  // Last write date
                                    Item[6].ToString() + "\t" +  // Last write time
                                    Item[7].ToString() + "\t" +  // Creation date
                                    Item[8].ToString() + "\t" +  // Creation time
                                    Item[9].ToString());         // SHA-256 hash
                }

                if (Convert.ToInt32(Item[0]) == 1)
                { // files only
                  // Files list for encryption
                  _FileList.Add(Item[1].ToString());  // Absolute file path
                                                      // Total file size
                  _TotalFileSize += Convert.ToInt64(Item[3]);
                }
                else
                { // Directory
                  _FileList.Add(Item[1].ToString());	// Absolute file path
                }

                FileNumber++;

              }// end foreach (ArrayList Item in GetFilesList(ParentPath, FilePath));

            }// if (File.Exists(FilePath) == true);

              }// end foreach (string FilePath in FilePaths);

              //----------------------------------------------------------------------
              // Check the disk space
              //----------------------------------------------------------------------
              string RootDriveLetter = Path.GetPathRoot(OutFilePath).Substring(0, 1);

              if (RootDriveLetter == "\\")
              {
            // Network
              }
              else
              {
            DriveInfo drive = new DriveInfo(RootDriveLetter);

            DriveType driveType = drive.DriveType;
            switch (driveType)
            {
              case DriveType.CDRom:
              case DriveType.NoRootDirectory:
              case DriveType.Unknown:
                break;
              case DriveType.Fixed:     // Local Drive
              case DriveType.Network:   // Mapped Drive
              case DriveType.Ram:       // Ram Drive
              case DriveType.Removable: // Usually a USB Drive

                // The drive is not available, or not enough free space.
                if (drive.IsReady == false || drive.AvailableFreeSpace < _TotalFileSize)
                {
                  e.Result = NO_DISK_SPACE;
                  // not available free space
                  return Tuple.Create(false, NO_DISK_SPACE);
                }
                break;
            }
              }

              //----------------------------------------------------------------------
              // Create header data

              string[] FileInfoText = (string[])FileInfoList.ToArray(typeof(string));

              byteArray = Encoding.UTF8.GetBytes(string.Join("\n", FileInfoText));
              ms.Write(byteArray, 0, byteArray.Length);

            #if (DEBUG)
              //Output text file of header contents for debug.
              Int64 NowPosition = ms.Position;
              ms.Position = 0;
              //Save to Desktop folder.
              string AppDirPath = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);
              string HeaderTextFilePath = Path.Combine(AppDirPath, "encrypt_header.txt");
              using (FileStream fsDebug = new FileStream(HeaderTextFilePath, FileMode.Create, FileAccess.Write))
              {
            ms.WriteTo(fsDebug);
            ms.Position = NowPosition;
              }
            #endif
              // The Header of MemoryStream is encrypted
              using (Rijndael aes = new RijndaelManaged())
              {
            aes.BlockSize = 256;              // BlockSize = 16bytes
            aes.KeySize = 256;                // KeySize = 16bytes
            aes.Mode = CipherMode.CBC;        // CBC mode
            //aes.Padding = PaddingMode.Zeros;  // Padding mode is "None".

            aes.Key = key;
            aes.IV = iv;

            ms.Position = 0;
            //Encryption interface.
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
            using (CryptoStream cse = new CryptoStream(outfs, encryptor, CryptoStreamMode.Write))
            {
              //----------------------------------------------------------------------
              // ヘッダーの暗号化
              //----------------------------------------------------------------------
              int len = 0;
              _AtcHeaderSize = 0;		// exclude IV of header
              buffer = new byte[BUFFER_SIZE];
              while ((len = ms.Read(buffer, 0, BUFFER_SIZE)) > 0)
              {
                cse.Write(buffer, 0, len);
                _AtcHeaderSize += len;
              }
            }

              }// end using (Rijndael aes = new RijndaelManaged());

            }// end  using (MemoryStream ms = new MemoryStream());

              }// end using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write));

              //----------------------------------------------------------------------
              // 本体データの暗号化
              //----------------------------------------------------------------------
              using (FileStream outfs = new FileStream(OutFilePath, FileMode.OpenOrCreate, FileAccess.Write))
              {
            try {
              byteArray = new byte[4];
              // Back to current positon of 'encrypted file size'
              if (_fExecutable == true)
              {
            outfs.Seek(ExeOutFileSize + 24, SeekOrigin.Begin);  // self executable file
              }
              else
              {
            outfs.Seek(24, SeekOrigin.Begin);
              }

              byteArray = BitConverter.GetBytes(_AtcHeaderSize);
              outfs.Write(byteArray, 0, 4);

              // Out file stream postion move to end
              outfs.Seek(0, SeekOrigin.End);

              // The Header of MemoryStream is encrypted
              using (Rijndael aes = new RijndaelManaged())
              {
            aes.BlockSize = 256;              // BlockSize = 16bytes
            aes.KeySize = 256;                // KeySize = 16bytes
            aes.Mode = CipherMode.CBC;        // CBC mode
            aes.Padding = PaddingMode.Zeros;  // Padding mode

            aes.Key = key;
            aes.IV = iv;

            // Encryption interface.
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
            using (CryptoStream cse = new CryptoStream(outfs, encryptor, CryptoStreamMode.Write))
            {
              Ionic.Zlib.CompressionLevel flv = Ionic.Zlib.CompressionLevel.Default;
              switch (AppSettings.Instance.CompressRate)
              {
                case 0:
                  flv = Ionic.Zlib.CompressionLevel.Level0;
                  break;
                case 1:
                  flv = Ionic.Zlib.CompressionLevel.Level1;
                  break;
                case 2:
                  flv = Ionic.Zlib.CompressionLevel.Level2;
                  break;
                case 3:
                  flv = Ionic.Zlib.CompressionLevel.Level3;
                  break;
                case 4:
                  flv = Ionic.Zlib.CompressionLevel.Level4;
                  break;
                case 5:
                  flv = Ionic.Zlib.CompressionLevel.Level5;
                  break;
                case 6:
                  flv = Ionic.Zlib.CompressionLevel.Level6;
                  break;
                case 7:
                  flv = Ionic.Zlib.CompressionLevel.Level7;
                  break;
                case 8:
                  flv = Ionic.Zlib.CompressionLevel.Level8;
                  break;
                case 9:
                  flv = Ionic.Zlib.CompressionLevel.Level9;
                  break;
              }

              using (Ionic.Zlib.DeflateStream ds = new Ionic.Zlib.DeflateStream(cse, Ionic.Zlib.CompressionMode.Compress, flv))
              {
                int len = 0;
                foreach (string path in _FileList)
                {
                  // Only file is encrypted
                  if (File.Exists(path) == true)
                  {
                    try
                    {
                      buffer = new byte[BUFFER_SIZE];
                      using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                      {
                        len = 0;
                        while ((len = fs.Read(buffer, 0, BUFFER_SIZE)) > 0)
                        {
                          ds.Write(buffer, 0, len);
                          _TotalSize += len;

                          string MessageText = "";
                          if (_TotalNumberOfFiles > 1)
                          {
                            MessageText = path + " ( " + _NumberOfFiles.ToString() + " / " + _TotalNumberOfFiles.ToString() + " files )";
                          }
                          else
                          {
                            MessageText = path;
                          }
                          float percent = ((float)_TotalSize / _TotalFileSize);
                          MessageList = new ArrayList();
                          MessageList.Add(ENCRYPTING);
                          MessageList.Add(MessageText);
                          worker.ReportProgress((int)(percent * 10000), MessageList);

                          if (worker.CancellationPending == true)
                          {
                            fs.Dispose();
                            e.Cancel = true;
                            return Tuple.Create(false, USER_CANCELED);
                          }

                        }

                      }

                    }
                    catch (Exception ex)
                    {
                      System.Windows.Forms.MessageBox.Show(ex.Message.ToString());
                      e.Result = ERROR_UNEXPECTED;
                      return Tuple.Create(false, ERROR_UNEXPECTED);
                    }

                  } // end if (File.Exists(path) == true);

                } // end foreach (string path in _FileList);

                /*
                for (int i = 0; i < 10; i++)
                {
                  Random r = new Random();
                  byteArray = new byte[BUFFER_SIZE];
                  r.NextBytes(byteArray);
                  cse.Write(buffer, 0, BUFFER_SIZE);
                }
                */

              } // end using ( Ionic.Zlib.DeflateStream ds);

            } // end using (CryptoStream cse);

              } // end using (Rijndael aes = new RijndaelManaged());

            }
            catch (Exception ex)
            {
              System.Windows.Forms.MessageBox.Show(ex.Message.ToString());
              e.Result = ERROR_UNEXPECTED;
              return Tuple.Create(false, ERROR_UNEXPECTED);
            }

              } // end using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write));

              // Set the timestamp of encryption file to original files or directories
              if (_fKeepTimeStamp == true)
              {
            File.SetCreationTime(OutFilePath, dtCreate);
            File.SetLastWriteTime(OutFilePath, dtUpdate);
            File.SetLastAccessTime(OutFilePath, dtAccess);
              }
              else
              {
            dtUpdate = DateTime.Now;
            File.SetLastWriteTime(OutFilePath, dtUpdate);
              }

              //Encryption succeed.
              e.Result = ENCRYPT_SUCCEEDED;
              return Tuple.Create(true, ENCRYPT_SUCCEEDED);
        }
Ejemplo n.º 18
0
        public bool Encrypt(
            object sender, DoWorkEventArgs e,
            string[] FilePaths, string OutFilePath,
            string Password, byte[] PasswordBinary,
            string NewArchiveName)
        {
#if (DEBUG)
            Logger lg = new Logger();
            lg.Info("-----------------------------------");
            lg.Info(OutFilePath);
            lg.Info("Encryotion satrt.");
            lg.StopWatchStart();
#endif

            _AtcFilePath = OutFilePath;

            BackgroundWorker worker = sender as BackgroundWorker;

            // The timestamp of original file
            DateTime dtCreate = File.GetCreationTime(FilePaths[0]);
            DateTime dtUpdate = File.GetLastWriteTime(FilePaths[0]);
            DateTime dtAccess = File.GetLastAccessTime(FilePaths[0]);

            // Create Header data.
            ArrayList MessageList = new ArrayList
            {
                READY_FOR_ENCRYPT,
                Path.GetFileName(_AtcFilePath)
            };
            worker.ReportProgress(0, MessageList);

            // Stopwatch for measuring time and adjusting the progress bar display
            Stopwatch swEncrypt  = new Stopwatch();
            Stopwatch swProgress = new Stopwatch();
            swEncrypt.Start();
            swProgress.Start();

            float percent = 0;

            _FileList = new List <string>();
            byte[] byteArray = null;

            // Salt
            Rfc2898DeriveBytes deriveBytes;
            if (PasswordBinary == null)
            { // String Password
                deriveBytes = new Rfc2898DeriveBytes(Password, 8, 1000);
            }
            else
            { // Binary Password
                byte[] random_salt           = new byte[8];
                RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
                rng.GetBytes(random_salt);
                deriveBytes = new Rfc2898DeriveBytes(PasswordBinary, random_salt, 1000);
            }
            byte[] salt = deriveBytes.Salt;
            byte[] key  = deriveBytes.GetBytes(32);
            byte[] iv   = deriveBytes.GetBytes(32);

            try
            {
                using (FileStream outfs = new FileStream(_AtcFilePath, FileMode.Create, FileAccess.Write))
                {
                    // 自己実行形式ファイル(Self-executable file)
                    if (_fExecutable == true)
                    {
                        // Read from ExeOut3.cs
                        ExeOutFileSize = rawData.Length;
                        outfs.Write(rawData, 0, (int)ExeOutFileSize);
                    }

                    _StartPos = outfs.Seek(0, SeekOrigin.End);

                    // Application version
                    Version ver    = ApplicationInfo.Version;
                    short   vernum = Int16.Parse(ver.ToString().Replace(".", ""));
                    byteArray = BitConverter.GetBytes(vernum);
                    outfs.Write(byteArray, 0, 2);
                    // Input password limit
                    byteArray = BitConverter.GetBytes(_MissTypeLimits);
                    outfs.Write(byteArray, 0, 1);
                    // Exceed the password input limit, destroy the file?
                    byteArray = BitConverter.GetBytes(fBrocken);
                    outfs.Write(byteArray, 0, 1);
                    // Token that this is the AttacheCase file
                    byteArray = Encoding.ASCII.GetBytes(STRING_TOKEN_NORMAL);
                    outfs.Write(byteArray, 0, 16);
                    // File sub version
                    byteArray = BitConverter.GetBytes(DATA_FILE_VERSION);
                    outfs.Write(byteArray, 0, 4);
                    // The size of encrypted Atc header size ( reserved )
                    byteArray = BitConverter.GetBytes((int)0);
                    outfs.Write(byteArray, 0, 4);
                    // Salt
                    outfs.Write(salt, 0, 8);

                    // Cipher text header.
                    using (MemoryStream ms = new MemoryStream())
                    {
                        byteArray = Encoding.ASCII.GetBytes(AtC_ENCRYPTED_TOKEN + "\n");
                        ms.Write(byteArray, 0, byteArray.Length);

                        int       FileNumber = 0;
                        string    ParentPath;
                        ArrayList FileInfoList = new ArrayList();

                        //----------------------------------------------------------------------
                        // Put together files in one ( Save as the name ).
                        // 複数ファイルを一つにまとめる(ファイルに名前をつけて保存)
                        if (NewArchiveName != "")
                        {
                            NewArchiveName = NewArchiveName + "\\";

                            // Now time
                            DateTime dtNow = new DateTime();
                            FileInfoList.Add("0:" +                                                        // File number
                                             NewArchiveName + "\t" +                                       // File name
                                             "0" + "\t" +                                                  // File size
                                             "16" + "\t" +                                                 // File attribute
                                             dtNow.Date.Subtract(new DateTime(1, 1, 1)).TotalDays + "\t" + // Last write date
                                             dtNow.TimeOfDay.TotalSeconds + "\t" +                         // Last write time
                                             dtNow.Date.Subtract(new DateTime(1, 1, 1)).TotalDays + "\t" + // Creation date
                                             dtNow.TimeOfDay.TotalSeconds + "\t" +                         // Creation time
                                             "" + "\t" +
                                                                                                           // ver.3.2.3.0 ~
                                             DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm:ss") + "\t" +
                                             DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm:ss"));
                            FileNumber++;
                        }

                        //----------------------------------------------------------------------
                        // When encrypt multiple files
                        // 複数のファイルを暗号化する場合
                        foreach (string FilePath in FilePaths)
                        {
                            ParentPath = Path.GetDirectoryName(FilePath);

                            if (ParentPath.EndsWith("\\") == false) // In case of 'C:\\' root direcroy.
                            {
                                ParentPath = ParentPath + "\\";
                            }

                            if ((worker.CancellationPending == true))
                            {
                                e.Cancel = true;
                                return(false);
                            }

                            //----------------------------------------------------------------------
                            // 暗号化リストを生成(ファイル)
                            // Create file to encrypt list ( File )
                            //----------------------------------------------------------------------
                            if (File.Exists(FilePath) == true)
                            {
                                ArrayList Item = GetFileInfo(ParentPath, FilePath);
                                FileInfoList.Add(FileNumber.ToString() + ":" + // File number
                                                                               //Item[0] + "\t" +           // TypeFlag ( Directory: 0, file: 1 )
                                                                               //Item[1] + "\t" +           // Absolute file path
                                                 NewArchiveName +
                                                 Item[2] + "\t" +              // Relative file path
                                                 Item[3].ToString() + "\t" +   // File size
                                                 Item[4].ToString() + "\t" +   // File attribute
                                                 Item[5].ToString() + "\t" +   // Last write date
                                                 Item[6].ToString() + "\t" +   // Last write time
                                                 Item[7].ToString() + "\t" +   // Creation date
                                                 Item[8].ToString() + "\t" +   // Creation time
                                                 Item[9].ToString() + "\t" +   // SHA-256 Hash string
                                                                               // ver.3.2.3.0 ~
                                                 Item[10].ToString() + "\t" +  // Last write date time(UTC)
                                                 Item[11].ToString());         // Creation date time(UTC)

                                // files only
                                if (Convert.ToInt32(Item[0]) == 1)
                                {
                                    // Files list for encryption
                                    _FileList.Add(Item[1].ToString()); // Absolute file path
                                                                       // Total file size
                                    _TotalFileSize += Convert.ToInt64(Item[3]);
                                }

                                FileNumber++;
                            }
                            //----------------------------------------------------------------------
                            // 暗号化リストを生成(ディレクトリ)
                            // Create file to encrypt list ( Directory )
                            //----------------------------------------------------------------------
                            else
                            {
                                // Directory
                                _FileList.Add(FilePath); // Absolute file path

                                foreach (ArrayList Item in GetFileList(ParentPath, FilePath))
                                {
                                    if ((worker.CancellationPending == true))
                                    {
                                        e.Cancel = true;
                                        return(false);
                                    }

                                    if (NewArchiveName != "")
                                    {
                                        Item[2] = NewArchiveName + "\\" + Item[2];
                                    }

                                    if ((int)Item[0] == 0)
                                    {                                                      // Directory
                                        FileInfoList.Add(FileNumber.ToString() + ":" +     // File number
                                                         NewArchiveName + Item[2] + "\t" + // Relative file path
                                                         Item[3].ToString() + "\t" +       // File size
                                                         Item[4].ToString() + "\t" +       // File attribute
                                                         Item[5].ToString() + "\t" +       // Last write date
                                                         Item[6].ToString() + "\t" +       // Last write time
                                                         Item[7].ToString() + "\t" +       // Creation date
                                                         Item[8].ToString() + "\t" +       // Creation time
                                                         "" + "\t" +
                                                                                           // ver.3.2.3.0 ~
                                                         Item[10].ToString() + "\t" +      // Last write date time(UTC)
                                                         Item[11].ToString());             // Creation date date time(UTC)
                                    }
                                    else
                                    {                                                      // File
                                        FileInfoList.Add(FileNumber.ToString() + ":" +     // File number
                                                         NewArchiveName + Item[2] + "\t" + // Relative file path
                                                         Item[3].ToString() + "\t" +       // File size
                                                         Item[4].ToString() + "\t" +       // File attribute
                                                         Item[5].ToString() + "\t" +       // Last write date
                                                         Item[6].ToString() + "\t" +       // Last write time
                                                         Item[7].ToString() + "\t" +       // Creation date
                                                         Item[8].ToString() + "\t" +       // Creation time
                                                         Item[9].ToString() + "\t" +       // SHA-256 hash
                                                                                           // ver.3.2.3.0 ~
                                                         Item[10].ToString() + "\t" +      // Last write date time(UTC)
                                                         Item[11].ToString());             // Creation date date time(UTC)
                                    }

                                    if (Convert.ToInt32(Item[0]) == 1)
                                    {                                      // files only
                                      // Files list for encryption
                                        _FileList.Add(Item[1].ToString()); // Absolute file path
                                                                           // Total file size
                                        _TotalFileSize += Convert.ToInt64(Item[3]);
                                    }
                                    else
                                    {                                      // Directory
                                        _FileList.Add(Item[1].ToString()); // Absolute file path
                                    }

                                    FileNumber++;
                                } // end foreach (ArrayList Item in GetFilesList(ParentPath, FilePath));
                            }     // if (File.Exists(FilePath) == true);
                        }         // end foreach (string FilePath in FilePaths);

                        //----------------------------------------------------------------------
                        // Check the disk space
                        //----------------------------------------------------------------------
                        string RootDriveLetter = Path.GetPathRoot(_AtcFilePath).Substring(0, 1);

                        if (RootDriveLetter == "\\")
                        {
                            // Network
                        }
                        else
                        {
                            DriveInfo drive = new DriveInfo(RootDriveLetter);

                            DriveType driveType = drive.DriveType;
                            switch (driveType)
                            {
                            case DriveType.CDRom:
                            case DriveType.NoRootDirectory:
                            case DriveType.Unknown:
                                break;

                            case DriveType.Fixed:     // Local Drive
                            case DriveType.Network:   // Mapped Drive
                            case DriveType.Ram:       // Ram Drive
                            case DriveType.Removable: // Usually a USB Drive

                                // The drive is not available, or not enough free space.
                                if (drive.IsReady == false || drive.AvailableFreeSpace < _TotalFileSize)
                                {
                                    // not available free space
                                    _ReturnCode = NO_DISK_SPACE;
                                    _DriveName  = drive.ToString();
                                    //_TotalFileSize = _TotalFileSize;
                                    _AvailableFreeSpace = drive.AvailableFreeSpace;
                                    return(false);
                                }
                                break;
                            }
                        }

                        //----------------------------------------------------------------------
                        // Create header data

                        string[] FileInfoText = (string[])FileInfoList.ToArray(typeof(string));
#if (DEBUG)
                        string DesktopPath      = System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
                        string FileListTextPath = Path.Combine(DesktopPath, "_header_text.txt");
                        var    FileListText     = String.Join("\n", FileInfoText);
                        System.IO.File.WriteAllText(FileListTextPath, FileListText, System.Text.Encoding.UTF8);
#endif
                        byteArray = Encoding.UTF8.GetBytes(string.Join("\n", FileInfoText));
                        ms.Write(byteArray, 0, byteArray.Length);

                        // The Header of MemoryStream is encrypted
                        using (Rijndael aes = new RijndaelManaged())
                        {
                            aes.BlockSize = 256;            // BlockSize = 16bytes
                            aes.KeySize   = 256;            // KeySize = 16bytes
                            aes.Mode      = CipherMode.CBC; // CBC mode
                                                            //aes.Padding = PaddingMode.Zeros;  // Padding mode is "None".
                            aes.Key = key;
                            aes.IV  = iv;

                            ms.Position = 0;
                            //Encryption interface.
                            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
                            using (CryptoStream cse = new CryptoStream(outfs, encryptor, CryptoStreamMode.Write))
                            {
                                //----------------------------------------------------------------------
                                // ヘッダーの暗号化
                                //----------------------------------------------------------------------
                                int len = 0;
                                _AtcHeaderSize = 0; // exclude IV of header
                                buffer         = new byte[BUFFER_SIZE];
                                while ((len = ms.Read(buffer, 0, BUFFER_SIZE)) > 0)
                                {
                                    cse.Write(buffer, 0, len);
                                    _AtcHeaderSize += len;
                                }
                            }
                        } // end using (Rijndael aes = new RijndaelManaged());
                    }     // end  using (MemoryStream ms = new MemoryStream());
                }         // end using (FileStream outfs = new FileStream(_AtcFilePath, FileMode.Create, FileAccess.Write));


                //----------------------------------------------------------------------
                // 本体データの暗号化
                //----------------------------------------------------------------------
                using (FileStream outfs = new FileStream(_AtcFilePath, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    byteArray = new byte[4];
                    // Back to current positon of 'encrypted file size'
                    if (_fExecutable == true)
                    {
                        outfs.Seek(ExeOutFileSize + 24, SeekOrigin.Begin); // self executable file
                    }
                    else
                    {
                        outfs.Seek(24, SeekOrigin.Begin);
                    }

                    byteArray = BitConverter.GetBytes(_AtcHeaderSize);
                    outfs.Write(byteArray, 0, 4);

                    // Out file stream postion move to end
                    outfs.Seek(0, SeekOrigin.End);

                    // The Header of MemoryStream is encrypted
                    using (Rijndael aes = new RijndaelManaged())
                    {
                        aes.BlockSize = 256;               // BlockSize = 16bytes
                        aes.KeySize   = 256;               // KeySize = 16bytes
                        aes.Mode      = CipherMode.CBC;    // CBC mode
                        aes.Padding   = PaddingMode.Zeros; // Padding mode

                        aes.Key = key;
                        aes.IV  = iv;

                        // Encryption interface.
                        ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
                        using (CryptoStream cse = new CryptoStream(outfs, encryptor, CryptoStreamMode.Write))
                        {
                            Ionic.Zlib.CompressionLevel flv = Ionic.Zlib.CompressionLevel.Default;
                            switch (AppSettings.Instance.CompressRate)
                            {
                            case 0:
                                flv = Ionic.Zlib.CompressionLevel.Level0;
                                break;

                            case 1:
                                flv = Ionic.Zlib.CompressionLevel.Level1;
                                break;

                            case 2:
                                flv = Ionic.Zlib.CompressionLevel.Level2;
                                break;

                            case 3:
                                flv = Ionic.Zlib.CompressionLevel.Level3;
                                break;

                            case 4:
                                flv = Ionic.Zlib.CompressionLevel.Level4;
                                break;

                            case 5:
                                flv = Ionic.Zlib.CompressionLevel.Level5;
                                break;

                            case 6:
                                flv = Ionic.Zlib.CompressionLevel.Level6;
                                break;

                            case 7:
                                flv = Ionic.Zlib.CompressionLevel.Level7;
                                break;

                            case 8:
                                flv = Ionic.Zlib.CompressionLevel.Level8;
                                break;

                            case 9:
                                flv = Ionic.Zlib.CompressionLevel.Level9;
                                break;
                            }

                            using (Ionic.Zlib.DeflateStream ds = new Ionic.Zlib.DeflateStream(cse, Ionic.Zlib.CompressionMode.Compress, flv))
                            {
                                int len = 0;
                                foreach (string path in _FileList)
                                {
                                    // Only file is encrypted
                                    if (File.Exists(path) == true)
                                    {
                                        buffer = new byte[BUFFER_SIZE];
                                        using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                                        {
                                            len = 0;
                                            while ((len = fs.Read(buffer, 0, BUFFER_SIZE)) > 0)
                                            {
                                                ds.Write(buffer, 0, len);
                                                _TotalSize += len;

                                                string MessageText = "";
                                                if (_TotalNumberOfFiles > 1)
                                                {
                                                    MessageText = path + " ( " + _NumberOfFiles.ToString() + " / " + _TotalNumberOfFiles.ToString() + " files )";
                                                }
                                                else
                                                {
                                                    MessageText = path;
                                                }

                                                MessageList = new ArrayList();
                                                MessageList.Add(ENCRYPTING);
                                                MessageList.Add(MessageText);

                                                // プログレスバーの更新間隔を100msに調整
                                                if (swProgress.ElapsedMilliseconds > 100)
                                                {
                                                    percent = ((float)_TotalSize / _TotalFileSize);
                                                    worker.ReportProgress((int)(percent * 10000), MessageList);
                                                    swProgress.Restart();
                                                }

                                                if (worker.CancellationPending == true)
                                                {
                                                    fs.Dispose();
                                                    e.Cancel = true;
                                                    return(false);
                                                }
                                            }
                                        }
                                    } // end if (File.Exists(path) == true);
                                }     // end foreach (string path in _FileList);

                                /*
                                 * for (int i = 0; i < 10; i++)
                                 * {
                                 * Random r = new Random();
                                 * byteArray = new byte[BUFFER_SIZE];
                                 * r.NextBytes(byteArray);
                                 * cse.Write(buffer, 0, BUFFER_SIZE);
                                 * }
                                 */
                            } // end using ( Ionic.Zlib.DeflateStream ds);
                        }     // end using (CryptoStream cse);
                    }         // end using (Rijndael aes = new RijndaelManaged());
                }             // end using (FileStream outfs = new FileStream(_AtcFilePath, FileMode.Create, FileAccess.Write));

                // Set the timestamp of encryption file to original files or directories
                if (_fKeepTimeStamp == true)
                {
                    File.SetCreationTime(_AtcFilePath, dtCreate);
                    File.SetLastWriteTime(_AtcFilePath, dtUpdate);
                    File.SetLastAccessTime(_AtcFilePath, dtAccess);
                }
                else
                {
                    dtUpdate = DateTime.Now;
                    File.SetLastWriteTime(_AtcFilePath, dtUpdate);
                }

                //Encryption succeed.
                _ReturnCode = ENCRYPT_SUCCEEDED;
                return(true);
            }
            catch (UnauthorizedAccessException)
            {
                //オペレーティング システムが I/O エラーまたは特定の種類のセキュリティエラーのためにアクセスを拒否する場合、スローされる例外
                //The exception that is thrown when the operating system denies access
                //because of an I/O error or a specific type of security error.
                _ReturnCode    = OS_DENIES_ACCESS;
                _ErrorFilePath = _AtcFilePath;
                return(false);
            }
            catch (DirectoryNotFoundException ex)
            {
                //ファイルまたはディレクトリの一部が見つからない場合にスローされる例外
                //The exception that is thrown when part of a file or directory cannot be found
                _ReturnCode   = DIRECTORY_NOT_FOUND;
                _ErrorMessage = ex.Message;
                return(false);
            }
            catch (DriveNotFoundException ex)
            {
                //使用できないドライブまたは共有にアクセスしようとするとスローされる例外
                //The exception that is thrown when trying to access a drive or share that is not available
                _ReturnCode   = DRIVE_NOT_FOUND;
                _ErrorMessage = ex.Message;
                return(false);
            }
            catch (FileLoadException ex)
            {
                //マネージド アセンブリが見つかったが、読み込むことができない場合にスローされる例外
                //The exception that is thrown when a managed assembly is found but cannot be loaded
                _ReturnCode    = FILE_NOT_LOADED;
                _ErrorFilePath = ex.FileName;
                return(false);
            }
            catch (FileNotFoundException ex)
            {
                //ディスク上に存在しないファイルにアクセスしようとして失敗したときにスローされる例外
                //The exception that is thrown when an attempt to access a file that does not exist on disk fails
                _ReturnCode    = FILE_NOT_FOUND;
                _ErrorFilePath = ex.FileName;
                return(false);
            }
            catch (PathTooLongException)
            {
                //パス名または完全修飾ファイル名がシステム定義の最大長を超えている場合にスローされる例外
                //The exception that is thrown when a path or fully qualified file name is longer than the system-defined maximum length
                _ReturnCode = PATH_TOO_LONG;
                return(false);
            }
            catch (IOException ex)
            {
                //I/Oエラーが発生したときにスローされる例外。現在の例外を説明するメッセージを取得します。
                //The exception that is thrown when an I/O error occurs. Gets a message that describes the current exception.
                _ReturnCode   = IO_EXCEPTION;
                _ErrorMessage = ex.Message;
                return(false);
            }
            catch (Exception ex)
            {
                _ReturnCode   = ERROR_UNEXPECTED;
                _ErrorMessage = ex.Message;
                return(false);
            }
            finally
            {
#if (DEBUG)
                lg.StopWatchStop();
                lg.Info("encryption finished!");
#endif
                swEncrypt.Stop();
                swProgress.Stop();
                // 計測時間
                TimeSpan ts = swEncrypt.Elapsed;
                _EncryptionTimeString =
                    Convert.ToString(ts.Hours) + "h" + Convert.ToString(ts.Minutes) + "m" +
                    Convert.ToString(ts.Seconds) + "s" + Convert.ToString(ts.Milliseconds) + "ms";
            }
        } // encrypt();
Ejemplo n.º 19
0
        /// <summary>
        /// Multiple files or directories is encrypted by AES (exactly Rijndael) to use password string.
        /// 複数のファイル、またはディレクトリをAES(正確にはRijndael)を使って指定のパスワードで暗号化する
        /// </summary>
        /// <param name="FilePath">File path or directory path is encrypted</param>
        /// <param name="OutFilePath">Output encryption file name</param>
        /// <param name="Password">Encription password string</param>
        /// <returns>Encryption success(true) or failed(false)</returns>
        public Tuple <bool, int> Encrypt(
            object sender, DoWorkEventArgs e,
            string[] FilePaths, string OutFilePath,
            string Password, byte[] PasswordBinary,
            string NewArchiveName)
        {
            byte[] bufferPassword;
            byte[] bufferKey = new byte[32];

            _AtcFilePath = OutFilePath;

            BackgroundWorker worker = sender as BackgroundWorker;

            //-----------------------------------
            // Header data is starting.
            // Progress event handler
            ArrayList MessageList = new ArrayList();

            MessageList.Add(READY_FOR_ENCRYPT);
            MessageList.Add(Path.GetFileName(OutFilePath));
            worker.ReportProgress(0, MessageList);

            _FileList = new List <string>();
            byte[] byteArray = null;

            using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write))
            {
                // 自己実行形式ファイル(Self-executable file)
                if (_fExecutable == true)
                {
                    ExeOutFileSize = rawData.Length;
                    outfs.Write(rawData, 0, (int)ExeOutFileSize);
                }

                _StartPos = outfs.Seek(0, SeekOrigin.End);

                byteArray = new byte[16];
                // Plain text header
                byteArray = BitConverter.GetBytes(DATA_SUB_VERSION);
                outfs.Write(byteArray, 0, 1);
                byteArray = null;
                byteArray = BitConverter.GetBytes(RESERVED_DATA);
                outfs.Write(byteArray, 0, 1);
                byteArray = null;
                byteArray = BitConverter.GetBytes(charMissTypeLimits);
                outfs.Write(byteArray, 0, 1);
                byteArray = null;
                byteArray = BitConverter.GetBytes(fBrocken);
                outfs.Write(byteArray, 0, 1);
                byteArray = null;
                byteArray = Encoding.ASCII.GetBytes(STRING_TOKEN_NORMAL);
                outfs.Write(byteArray, 0, 16);

                byteArray = null;
                byteArray = BitConverter.GetBytes(DATA_FILE_VERSION);
                outfs.Write(byteArray, 0, 4);
                byteArray = null;
                byteArray = BitConverter.GetBytes(TYPE_ALGORISM);
                outfs.Write(byteArray, 0, 4);

                // Reserve cipher text header size after encrypting.
                byteArray = null;
                byteArray = BitConverter.GetBytes(_AtcHeaderSize);
                outfs.Write(byteArray, 0, 4);

                // Cipher text header.
                using (MemoryStream ms = new MemoryStream())
                {
                    byteArray = Encoding.ASCII.GetBytes("Passcode:AttacheCase\n");
                    ms.Write(byteArray, 0, byteArray.Length);

                    DateTime dt = DateTime.Now;
                    byteArray = Encoding.ASCII.GetBytes("LastDateTime:" + dt.ToString("yyyy/MM/dd HH:mm:ss\n"));
                    ms.Write(byteArray, 0, byteArray.Length);

                    int       FileNumber = 0;
                    string    ParentPath;
                    ArrayList FileInfoList = new ArrayList();

                    //----------------------------------------------------------------------
                    // Put together files in one ( Save as the name ).
                    // 複数ファイルを一つにまとめる(ファイルに名前をつけて保存)
                    if (NewArchiveName != "")
                    {
                        // Now time
                        DateTime dtNow = new DateTime();
                        FileInfoList.Add("Fn_0:" +                                                     // File number
                                         NewArchiveName + "\\\t" +                                     // File name
                                         "0" + "\t" +                                                  // File size
                                         "16" + "\t" +                                                 // File attribute
                                         dtNow.Date.Subtract(new DateTime(1, 1, 1)).TotalDays + "\t" + // Last write date
                                         dtNow.TimeOfDay.TotalSeconds + "\t" +                         // Last write time
                                         dtNow.Date.Subtract(new DateTime(1, 1, 1)).TotalDays + "\t" + // Creation date
                                         dtNow.TimeOfDay.TotalSeconds);                                // Creation time
                        FileNumber++;
                    }

                    //----------------------------------------------------------------------
                    // When encrypt multiple files
                    // 複数のファイルを暗号化する場合
                    foreach (string FilePath in FilePaths)
                    {
                        ParentPath = Path.GetDirectoryName(FilePath) + "\\";

                        if ((worker.CancellationPending == true))
                        {
                            e.Cancel = true;
                            return(Tuple.Create(false, USER_CANCELED));
                        }

                        //----------------------------------------------------------------------
                        // 暗号化リストを生成(ファイル)
                        // Create file to encrypt list ( File )
                        //----------------------------------------------------------------------
                        if (File.Exists(FilePath) == true)
                        {
                            ArrayList Item = GetFileInfo(ParentPath, FilePath);
                            FileInfoList.Add("Fn_" + FileNumber.ToString() + ":" + // File number
                                                                                   //Item[0] + "\t" +                      // TypeFlag ( Directory: 0, file: 1 )
                                                                                   //Item[1] + "\t" +                      // Absolute file path
                                             Item[2] + "\t" +                      // Relative file path
                                             Item[3].ToString() + "\t" +           // File size
                                             Item[4].ToString() + "\t" +           // File attribute
                                             Item[5].ToString() + "\t" +           // Last write date
                                             Item[6].ToString() + "\t" +           // Last write time
                                             Item[7].ToString() + "\t" +           // Creation date
                                             Item[8].ToString());                  // Creation time

                            // files only
                            if (Convert.ToInt32(Item[0]) == 1)
                            {
                                // Files list for encryption
                                _FileList.Add(Item[1].ToString());                                      // Absolute file path
                                // Total file size
                                _TotalFileSize += Convert.ToInt64(Item[3]);
                            }

                            FileNumber++;
                        }
                        //----------------------------------------------------------------------
                        // 暗号化リストを生成(ディレクトリ)
                        // Create file to encrypt list ( Directory )
                        //----------------------------------------------------------------------
                        else
                        {
                            // Directory
                            _FileList.Add(FilePath); // Absolute file path

                            foreach (ArrayList Item in GetFileList(ParentPath, FilePath))
                            {
                                if ((worker.CancellationPending == true))
                                {
                                    e.Cancel = true;
                                    return(Tuple.Create(false, USER_CANCELED));
                                }

                                if (NewArchiveName != "")
                                {
                                    Item[2] = NewArchiveName + "\\" + Item[2];
                                }

                                FileInfoList.Add("Fn_" + FileNumber.ToString() + ":" + // File number
                                                                                       //Item[0] + "\t" +                      // TypeFlag ( Directory: 0, file: 1 )
                                                                                       //Item[1] + "\t" +                      // Absolute file path
                                                 Item[2] + "\t" +                      // Relative file path
                                                 Item[3].ToString() + "\t" +           // File size
                                                 Item[4].ToString() + "\t" +           // File attribute
                                                 Item[5].ToString() + "\t" +           // Last write date
                                                 Item[6].ToString() + "\t" +           // Last write time
                                                 Item[7].ToString() + "\t" +           // Creation date
                                                 Item[8].ToString());                  // Creation time

                                if (Convert.ToInt32(Item[0]) == 1)
                                {                                      // files only
                                  // Files list for encryption
                                    _FileList.Add(Item[1].ToString()); // Absolute file path
                                    // Total file size
                                    _TotalFileSize += Convert.ToInt64(Item[3]);
                                }
                                else
                                {                                      // Directory
                                    _FileList.Add(Item[1].ToString()); // Absolute file path
                                }

                                FileNumber++;
                            }            // end foreach (ArrayList Item in GetFilesList(ParentPath, FilePath));
                        }
                    }                    // end foreach (string FilePath in FilePaths);

                    //----------------------------------------------------------------------
                    // Check the disk space
                    //----------------------------------------------------------------------
                    string RootDriveLetter = Path.GetPathRoot(OutFilePath).Substring(0, 1);

                    if (RootDriveLetter == "\\")
                    {
                        // Network
                    }
                    else
                    {
                        DriveInfo drive = new DriveInfo(RootDriveLetter);

                        DriveType driveType = drive.DriveType;
                        switch (driveType)
                        {
                        case DriveType.CDRom:
                        case DriveType.NoRootDirectory:
                        case DriveType.Unknown:
                            break;

                        case DriveType.Fixed:     // Local Drive
                        case DriveType.Network:   // Mapped Drive
                        case DriveType.Ram:       // Ram Drive
                        case DriveType.Removable: // Usually a USB Drive

                            // The drive is not available, or not enough free space.
                            if (drive.IsReady == false || drive.AvailableFreeSpace < _TotalFileSize)
                            {
                                e.Result = NO_DISK_SPACE;
                                // not available free space
                                return(Tuple.Create(false, NO_DISK_SPACE));
                            }
                            break;
                        }
                    }

                    //----------------------------------------------------------------------
                    // Create header data

                    string[] FileInfoText = (string[])FileInfoList.ToArray(typeof(string));

                    // Shift-JIS ( Japanese )
                    byteArray = Encoding.GetEncoding(932).GetBytes(string.Join("\n", FileInfoText));
                    ms.Write(byteArray, 0, byteArray.Length);
                    Console.WriteLine(FileInfoText);
                    // UTF-8
                    byteArray = Encoding.UTF8.GetBytes("\n" + string.Join("\n", FileInfoText).Replace("Fn_", "U_"));
                    ms.Write(byteArray, 0, byteArray.Length);
                    Console.WriteLine(FileInfoText);

#if (DEBUG)
                    //Output text file of header contents for debug.
                    Int64 NowPosition = ms.Position;
                    ms.Position = 0;
                    //Save to Desktop folder.
                    string     DesktopPath        = System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
                    string     HeaderTextFilePath = Path.Combine(DesktopPath, "encrypt_header.txt");
                    FileStream fsDebug            = new FileStream(HeaderTextFilePath, FileMode.Create, FileAccess.Write);
                    ms.WriteTo(fsDebug);
                    fsDebug.Close();
                    ms.Position = NowPosition;
#endif
                    // The Header of MemoryStream is encrypted
                    using (Rijndael aes = new RijndaelManaged())
                    {
                        aes.BlockSize = 256;            // BlockSize = 16bytes
                        aes.KeySize   = 256;            // KeySize = 16bytes
                        aes.Mode      = CipherMode.CBC; // CBC mode
                        //aes.Padding = PaddingMode.Zeros;  // Padding mode is "None".

                        // Password
                        if (PasswordBinary != null)
                        {                               // Binary
                            bufferPassword = PasswordBinary;
                        }
                        else
                        {                               // Text
                            bufferPassword = Encoding.UTF8.GetBytes(Password);
                            //byte[] bufferPassword = Encoding.GetEncoding(932).GetBytes(Password);  // Shift-JIS
                        }

                        // Password is 256 bit, so truncated up to 32 bytes or fill up the data size.
                        // パスワードは256 bitなので、32バイトまで切り詰めるか、あるいはそのサイズまで埋める処理
                        for (int i = 0; i < bufferKey.Length; i++)
                        {
                            if (i < bufferPassword.Length)
                            {
                                // Cut down to 32 bytes characters.
                                bufferKey[i] = bufferPassword[i];
                            }
                            else
                            {
                                bufferKey[i] = 0;                                       // Zero filled
                            }
                        }
                        aes.Key = bufferKey;

                        // Initilization Vector
                        aes.GenerateIV();
                        outfs.Write(aes.IV, 0, 32);

                        ms.Position = 0;
                        //Encryption interface.
                        ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
                        using (CryptoStream cse = new CryptoStream(outfs, encryptor, CryptoStreamMode.Write))
                        {
                            //----------------------------------------------------------------------
                            // ヘッダーの暗号化
                            //----------------------------------------------------------------------
                            int len = 0;
                            _AtcHeaderSize = 0;                                         // exclude IV of header
                            buffer         = new byte[BUFFER_SIZE];
                            while ((len = ms.Read(buffer, 0, BUFFER_SIZE)) > 0)
                            {
                                cse.Write(buffer, 0, len);
                                _AtcHeaderSize += len;
                            }
                        }
                    }    // end using (Rijndael aes = new RijndaelManaged());
                }        // end  using (MemoryStream ms = new MemoryStream());
            }            // end using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write));


            //----------------------------------------------------------------------
            // 本体データの暗号化
            //----------------------------------------------------------------------
            using (FileStream outfs = new FileStream(OutFilePath, FileMode.OpenOrCreate, FileAccess.Write))
            {
                byteArray = new byte[4];
                // Back to current positon of 'encrypted file size'
                if (_fExecutable == true)
                {
                    outfs.Seek(ExeOutFileSize + 28, SeekOrigin.Begin);                          // self executable file
                }
                else
                {
                    outfs.Seek(28, SeekOrigin.Begin);
                }

                byteArray = BitConverter.GetBytes(_AtcHeaderSize);
                outfs.Write(byteArray, 0, 4);

                // Out file stream postion move to end
                outfs.Seek(0, SeekOrigin.End);

                // The Header of MemoryStream is encrypted
                using (Rijndael aes = new RijndaelManaged())
                {
                    aes.BlockSize = 256;                                  // BlockSize = 16bytes
                    aes.KeySize   = 256;                                  // KeySize = 16bytes
                    aes.Mode      = CipherMode.CBC;                       // CBC mode
                    //aes.Padding = PaddingMode.PKCS7;  // Padding mode is "PKCS7".

                    // Password is 256 bit, so truncated up to 32 bytes or fill up the data size.
                    for (int i = 0; i < bufferKey.Length; i++)
                    {
                        if (i < bufferPassword.Length)
                        {
                            //Cut down to 32bytes characters.
                            bufferKey[i] = bufferPassword[i];
                        }
                        else
                        {
                            bufferKey[i] = 0;
                        }
                    }
                    aes.Key = bufferKey;
                    // Initilization Vector
                    byte[] iv = new byte[32];
                    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
                    rng.GetNonZeroBytes(iv);
                    aes.IV = iv;

                    outfs.Write(iv, 0, 32);

                    // Encryption interface.
                    ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
                    using (CryptoStream cse = new CryptoStream(outfs, encryptor, CryptoStreamMode.Write))
                    {
                        // zlib 2bytes header
                        cse.WriteByte(0x78);

                        // cse.WriteByte(0x01);	//No Compression/low
                        cse.WriteByte(0x9C); //Default Compression
                        //cse.WriteByte(0xDA);	 //Best Compression

                        Ionic.Zlib.CompressionLevel flv = Ionic.Zlib.CompressionLevel.Default;
                        switch (AppSettings.Instance.CompressRate)
                        {
                        case 0:
                            flv = Ionic.Zlib.CompressionLevel.Level0;
                            break;

                        case 1:
                            flv = Ionic.Zlib.CompressionLevel.Level1;
                            break;

                        case 2:
                            flv = Ionic.Zlib.CompressionLevel.Level2;
                            break;

                        case 3:
                            flv = Ionic.Zlib.CompressionLevel.Level3;
                            break;

                        case 4:
                            flv = Ionic.Zlib.CompressionLevel.Level4;
                            break;

                        case 5:
                            flv = Ionic.Zlib.CompressionLevel.Level5;
                            break;

                        case 6:
                            flv = Ionic.Zlib.CompressionLevel.Level6;
                            break;

                        case 7:
                            flv = Ionic.Zlib.CompressionLevel.Level7;
                            break;

                        case 8:
                            flv = Ionic.Zlib.CompressionLevel.Level8;
                            break;

                        case 9:
                            flv = Ionic.Zlib.CompressionLevel.Level9;
                            break;
                        }

                        using (Ionic.Zlib.DeflateStream ds = new Ionic.Zlib.DeflateStream(cse, Ionic.Zlib.CompressionMode.Compress, flv))
                        {
                            int len = 0;
                            foreach (string path in _FileList)
                            {
                                // Only file is encrypted
                                if (File.Exists(path) == true)
                                {
                                    buffer = new byte[BUFFER_SIZE];
                                    using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
                                    {
                                        len = 0;
                                        while ((len = fs.Read(buffer, 0, BUFFER_SIZE)) > 0)
                                        {
                                            ds.Write(buffer, 0, len);
                                            _TotalSize += len;

                                            string MessageText = "";
                                            if (_TotalNumberOfFiles > 1)
                                            {
                                                MessageText = path + " ( " + _NumberOfFiles.ToString() + " files/ " + _TotalNumberOfFiles.ToString() + " folders )";
                                            }
                                            else
                                            {
                                                MessageText = path;
                                            }

                                            MessageList = new ArrayList();
                                            MessageList.Add(DECRYPTING);
                                            MessageList.Add(MessageText);
                                            float percent = ((float)_TotalSize / _TotalFileSize);
                                            worker.ReportProgress((int)(percent * 10000), MessageList);

                                            if (worker.CancellationPending == true)
                                            {
                                                e.Cancel = true;
                                                return(Tuple.Create(false, USER_CANCELED));
                                            }
                                        }
                                    }
                                }                         // end if (File.Exists(path) == true);
                            }                             // end foreach (string path in _FileList);

                            /*
                             * Random r = new Random();
                             * byteArray = new byte[BUFFER_SIZE];
                             * r.NextBytes(byteArray);
                             * ds.Write(buffer, 0, BUFFER_SIZE);
                             */
                        } // end using ( Ionic.Zlib.DeflateStream ds);
                    }     // end using (CryptoStream cse);
                }                 // end using (Rijndael aes = new RijndaelManaged());
            }             // end using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write));

            // Self-executable file
            if (fExecutable == true)
            {
                using (FileStream outfs = new FileStream(OutFilePath, FileMode.Open, FileAccess.Write))
                {
                    Int64 DataSize = outfs.Seek(0, SeekOrigin.End);
                    DataSize  = DataSize - _StartPos;
                    byteArray = BitConverter.GetBytes(DataSize);
                    outfs.Write(byteArray, 0, sizeof(Int64));
                }
            }

            // Set the timestamp of encryption file to original files or directories
            if (_fKeepTimeStamp == true)
            {
                DateTime dtCreate = File.GetCreationTime((string)AppSettings.Instance.FileList[0]);
                DateTime dtUpdate = File.GetLastWriteTime((string)AppSettings.Instance.FileList[0]);
                DateTime dtAccess = File.GetLastAccessTime((string)AppSettings.Instance.FileList[0]);
                File.SetCreationTime(OutFilePath, dtCreate);
                File.SetLastWriteTime(OutFilePath, dtUpdate);
                File.SetLastAccessTime(OutFilePath, dtAccess);
            }

            //Encryption succeed.
            e.Result = ENCRYPT_SUCCEEDED;
            return(Tuple.Create(true, ENCRYPT_SUCCEEDED));
        } // encrypt();
Ejemplo n.º 20
0
        /// <summary>
        /// Multiple files or directories is encrypted by AES (exactly Rijndael) to use password string.
        /// 複数のファイル、またはディレクトリをAES(正確にはRijndael)を使って指定のパスワードで暗号化する
        /// </summary>
        /// <param name="FilePath">File path or directory path is encrypted</param>
        /// <param name="OutFilePath">Output encryption file name</param>
        /// <param name="Password">Encription password string</param>
        /// <returns>Encryption success(true) or failed(false)</returns>
        public Tuple <bool, int> Encrypt(
            object sender, DoWorkEventArgs e,
            string[] FilePaths, string OutFilePath,
            string Password, byte[] PasswordBinary,
            string NewArchiveName)
        {
            _AtcFilePath = OutFilePath;

            BackgroundWorker worker = sender as BackgroundWorker;

            // The timestamp of original file
            DateTime dtCreate = File.GetCreationTime(FilePaths[0]);
            DateTime dtUpdate = File.GetLastWriteTime(FilePaths[0]);
            DateTime dtAccess = File.GetLastAccessTime(FilePaths[0]);

            // Create Header data.
            ArrayList MessageList = new ArrayList();

            MessageList.Add(READY_FOR_ENCRYPT);
            MessageList.Add(Path.GetFileName(OutFilePath));
            worker.ReportProgress(0, MessageList);

            _FileList = new List <string>();
            byte[] byteArray = null;

            // Salt
            Rfc2898DeriveBytes deriveBytes;

            if (PasswordBinary == null)
            { // String Password
                deriveBytes = new Rfc2898DeriveBytes(Password, 8, 1000);
            }
            else
            { // Binary Password
                byte[] random_salt           = new byte[8];
                RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
                rng.GetBytes(random_salt);
                deriveBytes = new Rfc2898DeriveBytes(PasswordBinary, random_salt, 1000);
            }
            byte[] salt = deriveBytes.Salt;
            byte[] key  = deriveBytes.GetBytes(32);
            byte[] iv   = deriveBytes.GetBytes(32);

            using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write))
            {
                // 自己実行形式ファイル(Self-executable file)
                if (_fExecutable == true)
                {
                    ExeOutFileSize = rawData.Length;
                    outfs.Write(rawData, 0, (int)ExeOutFileSize);
                }

                _StartPos = outfs.Seek(0, SeekOrigin.End);

                // Application version
                Version ver    = ApplicationInfo.Version;
                short   vernum = Int16.Parse(ver.ToString().Replace(".", ""));
                byteArray = BitConverter.GetBytes(vernum);
                outfs.Write(byteArray, 0, 2);
                // Input password limit
                byteArray = BitConverter.GetBytes(_MissTypeLimits);
                outfs.Write(byteArray, 0, 1);
                // Exceed the password input limit, destroy the file?
                byteArray = BitConverter.GetBytes(fBrocken);
                outfs.Write(byteArray, 0, 1);
                // Token that this is the AttacheCase file
                byteArray = Encoding.ASCII.GetBytes(STRING_TOKEN_NORMAL);
                outfs.Write(byteArray, 0, 16);
                // File sub version
                byteArray = BitConverter.GetBytes(DATA_FILE_VERSION);
                outfs.Write(byteArray, 0, 4);
                // The size of encrypted Atc header size ( reserved )
                byteArray = BitConverter.GetBytes((int)0);
                outfs.Write(byteArray, 0, 4);
                // Salt
                outfs.Write(salt, 0, 8);

                // Cipher text header.
                using (MemoryStream ms = new MemoryStream())
                {
                    byteArray = Encoding.ASCII.GetBytes(AtC_ENCRYPTED_TOKEN + "\n");
                    ms.Write(byteArray, 0, byteArray.Length);

                    int       FileNumber = 0;
                    string    ParentPath;
                    ArrayList FileInfoList = new ArrayList();

                    //----------------------------------------------------------------------
                    // Put together files in one ( Save as the name ).
                    // 複数ファイルを一つにまとめる(ファイルに名前をつけて保存)
                    if (NewArchiveName != "")
                    {
                        // Now time
                        DateTime dtNow = new DateTime();
                        FileInfoList.Add("0:" +                                                        // File number
                                         NewArchiveName + "\\\t" +                                     // File name
                                         "0" + "\t" +                                                  // File size
                                         "16" + "\t" +                                                 // File attribute
                                         dtNow.Date.Subtract(new DateTime(1, 1, 1)).TotalDays + "\t" + // Last write date
                                         dtNow.TimeOfDay.TotalSeconds + "\t" +                         // Last write time
                                         dtNow.Date.Subtract(new DateTime(1, 1, 1)).TotalDays + "\t" + // Creation date
                                         dtNow.TimeOfDay.TotalSeconds);                                // Creation time
                        FileNumber++;
                    }

                    //----------------------------------------------------------------------
                    // When encrypt multiple files
                    // 複数のファイルを暗号化する場合
                    foreach (string FilePath in FilePaths)
                    {
                        ParentPath = Path.GetDirectoryName(FilePath);

                        if (ParentPath.EndsWith("\\") == false) // In case of 'C:\\' root direcroy.
                        {
                            ParentPath = ParentPath + "\\";
                        }

                        if ((worker.CancellationPending == true))
                        {
                            e.Cancel = true;
                            return(Tuple.Create(false, USER_CANCELED));
                        }

                        //----------------------------------------------------------------------
                        // 暗号化リストを生成(ファイル)
                        // Create file to encrypt list ( File )
                        //----------------------------------------------------------------------
                        if (File.Exists(FilePath) == true)
                        {
                            ArrayList Item = GetFileInfo(ParentPath, FilePath);
                            FileInfoList.Add(FileNumber.ToString() + ":" + // File number
                                                                           //Item[0] + "\t" +           // TypeFlag ( Directory: 0, file: 1 )
                                                                           //Item[1] + "\t" +           // Absolute file path
                                             Item[2] + "\t" +              // Relative file path
                                             Item[3].ToString() + "\t" +   // File size
                                             Item[4].ToString() + "\t" +   // File attribute
                                             Item[5].ToString() + "\t" +   // Last write date
                                             Item[6].ToString() + "\t" +   // Last write time
                                             Item[7].ToString() + "\t" +   // Creation date
                                             Item[8].ToString() + "\t" +   // Creation time
                                             Item[9].ToString());          // SHA-256 Hash string

                            // files only
                            if (Convert.ToInt32(Item[0]) == 1)
                            {
                                // Files list for encryption
                                _FileList.Add(Item[1].ToString()); // Absolute file path
                                                                   // Total file size
                                _TotalFileSize += Convert.ToInt64(Item[3]);
                            }

                            FileNumber++;
                        }
                        //----------------------------------------------------------------------
                        // 暗号化リストを生成(ディレクトリ)
                        // Create file to encrypt list ( Directory )
                        //----------------------------------------------------------------------
                        else
                        {
                            // Directory
                            _FileList.Add(FilePath); // Absolute file path

                            foreach (ArrayList Item in GetFileList(ParentPath, FilePath))
                            {
                                if ((worker.CancellationPending == true))
                                {
                                    e.Cancel = true;
                                    return(Tuple.Create(false, USER_CANCELED));
                                }

                                if (NewArchiveName != "")
                                {
                                    Item[2] = NewArchiveName + "\\" + Item[2];
                                }

                                if ((int)Item[0] == 0)
                                {                                                  // Directory
                                    FileInfoList.Add(FileNumber.ToString() + ":" + // File number
                                                     Item[2] + "\t" +              // Relative file path
                                                     Item[3].ToString() + "\t" +   // File size
                                                     Item[4].ToString() + "\t" +   // File attribute
                                                     Item[5].ToString() + "\t" +   // Last write date
                                                     Item[6].ToString() + "\t" +   // Last write time
                                                     Item[7].ToString() + "\t" +   // Creation date
                                                     Item[8].ToString());          // Creation time
                                }
                                else
                                {                                                  // File
                                    FileInfoList.Add(FileNumber.ToString() + ":" + // File number
                                                     Item[2] + "\t" +              // Relative file path
                                                     Item[3].ToString() + "\t" +   // File size
                                                     Item[4].ToString() + "\t" +   // File attribute
                                                     Item[5].ToString() + "\t" +   // Last write date
                                                     Item[6].ToString() + "\t" +   // Last write time
                                                     Item[7].ToString() + "\t" +   // Creation date
                                                     Item[8].ToString() + "\t" +   // Creation time
                                                     Item[9].ToString());          // SHA-256 hash
                                }

                                if (Convert.ToInt32(Item[0]) == 1)
                                {                                      // files only
                                  // Files list for encryption
                                    _FileList.Add(Item[1].ToString()); // Absolute file path
                                                                       // Total file size
                                    _TotalFileSize += Convert.ToInt64(Item[3]);
                                }
                                else
                                {                                      // Directory
                                    _FileList.Add(Item[1].ToString()); // Absolute file path
                                }

                                FileNumber++;
                            } // end foreach (ArrayList Item in GetFilesList(ParentPath, FilePath));
                        }     // if (File.Exists(FilePath) == true);
                    }         // end foreach (string FilePath in FilePaths);

                    //----------------------------------------------------------------------
                    // Check the disk space
                    //----------------------------------------------------------------------
                    string RootDriveLetter = Path.GetPathRoot(OutFilePath).Substring(0, 1);

                    if (RootDriveLetter == "\\")
                    {
                        // Network
                    }
                    else
                    {
                        DriveInfo drive = new DriveInfo(RootDriveLetter);

                        DriveType driveType = drive.DriveType;
                        switch (driveType)
                        {
                        case DriveType.CDRom:
                        case DriveType.NoRootDirectory:
                        case DriveType.Unknown:
                            break;

                        case DriveType.Fixed:     // Local Drive
                        case DriveType.Network:   // Mapped Drive
                        case DriveType.Ram:       // Ram Drive
                        case DriveType.Removable: // Usually a USB Drive

                            // The drive is not available, or not enough free space.
                            if (drive.IsReady == false || drive.AvailableFreeSpace < _TotalFileSize)
                            {
                                e.Result = NO_DISK_SPACE;
                                // not available free space
                                return(Tuple.Create(false, NO_DISK_SPACE));
                            }
                            break;
                        }
                    }

                    //----------------------------------------------------------------------
                    // Create header data

                    string[] FileInfoText = (string[])FileInfoList.ToArray(typeof(string));

                    byteArray = Encoding.UTF8.GetBytes(string.Join("\n", FileInfoText));
                    ms.Write(byteArray, 0, byteArray.Length);

#if (DEBUG)
                    //Output text file of header contents for debug.
                    Int64 NowPosition = ms.Position;
                    ms.Position = 0;
                    //Save to Desktop folder.
                    string AppDirPath         = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);
                    string HeaderTextFilePath = Path.Combine(AppDirPath, "encrypt_header.txt");
                    using (FileStream fsDebug = new FileStream(HeaderTextFilePath, FileMode.Create, FileAccess.Write))
                    {
                        ms.WriteTo(fsDebug);
                        ms.Position = NowPosition;
                    }
#endif
                    // The Header of MemoryStream is encrypted
                    using (Rijndael aes = new RijndaelManaged())
                    {
                        aes.BlockSize = 256;            // BlockSize = 16bytes
                        aes.KeySize   = 256;            // KeySize = 16bytes
                        aes.Mode      = CipherMode.CBC; // CBC mode
                        //aes.Padding = PaddingMode.Zeros;  // Padding mode is "None".

                        aes.Key = key;
                        aes.IV  = iv;

                        ms.Position = 0;
                        //Encryption interface.
                        ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
                        using (CryptoStream cse = new CryptoStream(outfs, encryptor, CryptoStreamMode.Write))
                        {
                            //----------------------------------------------------------------------
                            // ヘッダーの暗号化
                            //----------------------------------------------------------------------
                            int len = 0;
                            _AtcHeaderSize = 0; // exclude IV of header
                            buffer         = new byte[BUFFER_SIZE];
                            while ((len = ms.Read(buffer, 0, BUFFER_SIZE)) > 0)
                            {
                                cse.Write(buffer, 0, len);
                                _AtcHeaderSize += len;
                            }
                        }
                    } // end using (Rijndael aes = new RijndaelManaged());
                }     // end  using (MemoryStream ms = new MemoryStream());
            }         // end using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write));


            //----------------------------------------------------------------------
            // 本体データの暗号化
            //----------------------------------------------------------------------
            using (FileStream outfs = new FileStream(OutFilePath, FileMode.OpenOrCreate, FileAccess.Write))
            {
                try {
                    byteArray = new byte[4];
                    // Back to current positon of 'encrypted file size'
                    if (_fExecutable == true)
                    {
                        outfs.Seek(ExeOutFileSize + 24, SeekOrigin.Begin); // self executable file
                    }
                    else
                    {
                        outfs.Seek(24, SeekOrigin.Begin);
                    }

                    byteArray = BitConverter.GetBytes(_AtcHeaderSize);
                    outfs.Write(byteArray, 0, 4);

                    // Out file stream postion move to end
                    outfs.Seek(0, SeekOrigin.End);

                    // The Header of MemoryStream is encrypted
                    using (Rijndael aes = new RijndaelManaged())
                    {
                        aes.BlockSize = 256;               // BlockSize = 16bytes
                        aes.KeySize   = 256;               // KeySize = 16bytes
                        aes.Mode      = CipherMode.CBC;    // CBC mode
                        aes.Padding   = PaddingMode.Zeros; // Padding mode

                        aes.Key = key;
                        aes.IV  = iv;

                        // Encryption interface.
                        ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
                        using (CryptoStream cse = new CryptoStream(outfs, encryptor, CryptoStreamMode.Write))
                        {
                            Ionic.Zlib.CompressionLevel flv = Ionic.Zlib.CompressionLevel.Default;
                            switch (AppSettings.Instance.CompressRate)
                            {
                            case 0:
                                flv = Ionic.Zlib.CompressionLevel.Level0;
                                break;

                            case 1:
                                flv = Ionic.Zlib.CompressionLevel.Level1;
                                break;

                            case 2:
                                flv = Ionic.Zlib.CompressionLevel.Level2;
                                break;

                            case 3:
                                flv = Ionic.Zlib.CompressionLevel.Level3;
                                break;

                            case 4:
                                flv = Ionic.Zlib.CompressionLevel.Level4;
                                break;

                            case 5:
                                flv = Ionic.Zlib.CompressionLevel.Level5;
                                break;

                            case 6:
                                flv = Ionic.Zlib.CompressionLevel.Level6;
                                break;

                            case 7:
                                flv = Ionic.Zlib.CompressionLevel.Level7;
                                break;

                            case 8:
                                flv = Ionic.Zlib.CompressionLevel.Level8;
                                break;

                            case 9:
                                flv = Ionic.Zlib.CompressionLevel.Level9;
                                break;
                            }

                            using (Ionic.Zlib.DeflateStream ds = new Ionic.Zlib.DeflateStream(cse, Ionic.Zlib.CompressionMode.Compress, flv))
                            {
                                int len = 0;
                                foreach (string path in _FileList)
                                {
                                    // Only file is encrypted
                                    if (File.Exists(path) == true)
                                    {
                                        try
                                        {
                                            buffer = new byte[BUFFER_SIZE];
                                            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                                            {
                                                len = 0;
                                                while ((len = fs.Read(buffer, 0, BUFFER_SIZE)) > 0)
                                                {
                                                    ds.Write(buffer, 0, len);
                                                    _TotalSize += len;

                                                    string MessageText = "";
                                                    if (_TotalNumberOfFiles > 1)
                                                    {
                                                        MessageText = path + " ( " + _NumberOfFiles.ToString() + " / " + _TotalNumberOfFiles.ToString() + " files )";
                                                    }
                                                    else
                                                    {
                                                        MessageText = path;
                                                    }
                                                    float percent = ((float)_TotalSize / _TotalFileSize);
                                                    MessageList = new ArrayList();
                                                    MessageList.Add(ENCRYPTING);
                                                    MessageList.Add(MessageText);
                                                    worker.ReportProgress((int)(percent * 10000), MessageList);

                                                    if (worker.CancellationPending == true)
                                                    {
                                                        fs.Dispose();
                                                        e.Cancel = true;
                                                        return(Tuple.Create(false, USER_CANCELED));
                                                    }
                                                }
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            System.Windows.Forms.MessageBox.Show(ex.Message.ToString());
                                            e.Result = ERROR_UNEXPECTED;
                                            return(Tuple.Create(false, ERROR_UNEXPECTED));
                                        }
                                    } // end if (File.Exists(path) == true);
                                }     // end foreach (string path in _FileList);

                                /*
                                 * for (int i = 0; i < 10; i++)
                                 * {
                                 * Random r = new Random();
                                 * byteArray = new byte[BUFFER_SIZE];
                                 * r.NextBytes(byteArray);
                                 * cse.Write(buffer, 0, BUFFER_SIZE);
                                 * }
                                 */
                            } // end using ( Ionic.Zlib.DeflateStream ds);
                        }     // end using (CryptoStream cse);
                    }         // end using (Rijndael aes = new RijndaelManaged());
                }
                catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show(ex.Message.ToString());
                    e.Result = ERROR_UNEXPECTED;
                    return(Tuple.Create(false, ERROR_UNEXPECTED));
                }
            } // end using (FileStream outfs = new FileStream(OutFilePath, FileMode.Create, FileAccess.Write));

            // Set the timestamp of encryption file to original files or directories
            if (_fKeepTimeStamp == true)
            {
                File.SetCreationTime(OutFilePath, dtCreate);
                File.SetLastWriteTime(OutFilePath, dtUpdate);
                File.SetLastAccessTime(OutFilePath, dtAccess);
            }
            else
            {
                dtUpdate = DateTime.Now;
                File.SetLastWriteTime(OutFilePath, dtUpdate);
            }

            //Encryption succeed.
            e.Result = ENCRYPT_SUCCEEDED;
            return(Tuple.Create(true, ENCRYPT_SUCCEEDED));
        } // encrypt();