星期五, 12月 23, 2016

[C#] 利用 DES 加解密

利用 DES 來加解密 txt 檔案,藉此了解檔案加解密是如何進行的

using System.IO;
using System.Security.Cryptography;

namespace DESPractice
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private string Dir = @"D:\CryptographyTemp";
        private string Content = string.Empty;
        private string DefaultTxtName = "Source.txt";

        private void Form1_Load(object sender, EventArgs e)
        {
            // 預設檔案路徑
            txtSourceFile.Text = Path.Combine(Dir, DefaultTxtName);
            txtEncryptSourceFile.Text = Path.Combine(Dir, "加密", DefaultTxtName);
            txtDecryptFile.Text = Path.Combine(new string[] { Dir, "解密", DefaultTxtName });

            // DESCrypto 所需的 Key 和 IV
            txtKey.Text = "12345678";
            txtIV.Text = "12345678";

            // 選擇來源檔案時,會一併建立 txt 測試檔案,此為 txt 檔案內容
            Content += "參考資料                                " + Environment.NewLine;
            Content += "* Encoding 類別                       " + Environment.NewLine;
            Content += "* ASCIIEncoding 類別                  " + Environment.NewLine;
            Content += "* Convert.ToBase64String 方法 (Byte[])" + Environment.NewLine;
            Content += "* StreamReader.ReadToEnd 方法()       " + Environment.NewLine;
            Content += "* Stream.CopyTo 方法                  " + Environment.NewLine;
            Content += "* 如何使用 Visual C# 加密和解密檔案     " + Environment.NewLine;

            btnSourceFile.Click += BtnClick;
            btnEncryptSourceFile.Click += BtnClick;
            btnDecryptFile.Click += BtnClick;
        }

        private void BtnClick(object sender, EventArgs e)
        {
            SaveFileDialog fd = new SaveFileDialog();
            fd.Filter = "(*.txt) | *.txt | All files(*.*) | *.*";
            fd.InitialDirectory = @"D:\CryptographyTemp";
            if (fd.ShowDialog() != DialogResult.OK) return;

            Button btn = sender as Button;
            string btnName = btn.Name;
            switch (btnName)
            {
                case "btnSourceFile":
                    txtSourceFile.Text = fd.FileName;
                    // 利用 File.WriteAllText() 把資料寫進去 txt 檔案
                    File.WriteAllText(fd.FileName, Content, Encoding.Default);
                    break;
                case "btnEncryptSourceFile":
                    txtEncryptSourceFile.Text = fd.FileName;
                    break;
                case "btnDecryptFile":
                    txtDecryptFile.Text = fd.FileName;
                    break;
                default:
                    break;
            }
        }

        private Tuple<byte[], byte[]> KeyIV(string key, string iv)
        {
            return new Tuple<byte[], byte[]>
                (
                    Encoding.ASCII.GetBytes(key),
                    Encoding.ASCII.GetBytes(iv)
                );
        }

        private void btnRunEncrypt_Click(object sender, EventArgs e)
        {
            DESCryptoServiceProvider des =
                new DESCryptoServiceProvider();

            Tuple<byte[], byte[]> result = KeyIV(txtKey.Text.Trim(), txtIV.Text.Trim());
            byte[] key = result.Item1;
            byte[] iv = result.Item2;

            // 來源檔案
            using (FileStream fsSource = new FileStream(
                  txtSourceFile.Text.Trim(),
                  FileMode.Open,
                  FileAccess.Read))
            // 加密檔案
            using (FileStream fsEncrypt = new FileStream(
                txtEncryptSourceFile.Text.Trim(),
                FileMode.Create,
                FileAccess.Write))
            // 進行加密
            using (CryptoStream cs = new CryptoStream(
               fsEncrypt,
               des.CreateEncryptor(key, iv),
               CryptoStreamMode.Write))
            {
                // CopyTo 是從 Stream 現在 Position 讀取到尾,避免 Position 不是在頭,要先設 Position = 0
                fsSource.Position = 0;
                fsSource.CopyTo(cs);
            }

            ReadTextFile();
        }

        private void btnRunDecrypt_Click(object sender, EventArgs e)
        {
            DESCryptoServiceProvider des =
                new DESCryptoServiceProvider();

            Tuple<byte[], byte[]> result = KeyIV(txtKey.Text.Trim(), txtIV.Text.Trim());
            byte[] key = result.Item1;
            byte[] iv = result.Item2;

            // 已加密檔案
            using (FileStream fsDecrypt = new FileStream(
                txtEncryptSourceFile.Text.Trim(),
                FileMode.Open,
                FileAccess.Read))
            // 進行解密
            using (CryptoStream cs = new CryptoStream(
                 fsDecrypt,
                 des.CreateDecryptor(key, iv),
                 CryptoStreamMode.Read))
            // 把解密後資料讀出來
            using (StreamReader sr = new StreamReader(cs, Encoding.Default))
            // 把解密後資料送進 txt 檔案內
            using (StreamWriter sw = new StreamWriter(txtDecryptFile.Text.Trim(), false, Encoding.Default))
            {
                string Content = sr.ReadToEnd();
                // 利用 StreamWriter() 把資料寫進檔案內,要把 Stream 關閉,資料才會寫進檔案內喔
                sw.Write(Content);
            }

            ReadTextFile();
        }

        private void ReadTextFile()
        {
            // 把資料送進 txtSource、txtEncrypt、txtDecrypt
            string Source = txtSourceFile.Text.Trim();
            if (File.Exists(Source))
            {
                using (StreamReader srSource = new StreamReader(Source, Encoding.Default))
                {
                    txtSource.Text = srSource.ReadToEnd();
                }
            }

            string Encrypt = txtEncryptSourceFile.Text.Trim();
            if (File.Exists(Encrypt))
            {
                using (StreamReader srEncrypt = new StreamReader(Encrypt, Encoding.Default))
                {
                    txtEncrypt.Text = srEncrypt.ReadToEnd();
                }
            }

            string Decrypt = txtDecryptFile.Text.Trim();
            if (File.Exists(Decrypt))
            {
                using (StreamReader srDecrypt = new StreamReader(Decrypt, Encoding.Default))
                {
                    string Content = srDecrypt.ReadToEnd();
                    txtDecrypt.Text = Content;
                }
            }
        }
    }
}
[C#] 加解密

沒有留言:

張貼留言