iT邦幫忙

DAY 6
2

c#應用系列 第 6

C#應用(6)加密與解密,以及雜湊值

  • 分享至 

  • xImage
  •  

*加密與解密, 用於資料保密(在台灣每年合法申請監聽的數量超過1.5萬件, 非法的監聽件數未知, 各位的Skype或LINE的傳訊內容, 或許早就被人看光光)
** AES, DES, TripleDES, RC2, RSA

*雜湊值, 則常用密碼字串儲存, 避免在資料庫裡使用明碼存放密碼, 以防資料庫外洩時, 密碼在第一時間被看光光
**MD5, SHA1

相關技術:
*System.Security.Cryptography Namespace

回目錄
*檔案 Encoder.cs

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

namespace Encoder.Security
{
    public enum EncoderType
    {
        //可逆編碼(對稱金鑰)
        AES,
        DES,
        RC2,
        TripleDES,

        //可逆編碼(非對稱金鑰)
        RSA,

        //不可逆編碼(雜湊值)
        MD5,
        SHA1,
        SHA256,
        SHA384,
        SHA512
    }

    public class Encoder
    {
        public string Key { get; set; }
        public string IV { get; set; }

        /// <summary>
        /// 產生新的KEY
        /// </summary>
        /// <param name="type">編碼器種類</param>
        public void GenerateKey(EncoderType type)
        {
            switch (type)
            {
                //可逆編碼(對稱金鑰)
                case EncoderType.AES:
                    using (AesCryptoServiceProvider csp = new AesCryptoServiceProvider())
                    {
                        csp.GenerateIV();
                        IV = Convert.ToBase64String(csp.IV);
                        csp.GenerateKey();
                        Key = Convert.ToBase64String(csp.Key);
                    }
                    break;
                case EncoderType.DES:
                    using (DESCryptoServiceProvider csp = new DESCryptoServiceProvider())
                    {
                        csp.GenerateIV();
                        IV = Convert.ToBase64String(csp.IV);
                        csp.GenerateKey();
                        Key = Convert.ToBase64String(csp.Key);                        
                    }
                    break;
                case EncoderType.RC2:
                    using (RC2CryptoServiceProvider csp = new RC2CryptoServiceProvider())
                    {
                        csp.GenerateIV();
                        IV = Convert.ToBase64String(csp.IV);
                        csp.GenerateKey();
                        Key = Convert.ToBase64String(csp.Key);
                    }
                    break;
                case EncoderType.TripleDES:
                    using (TripleDESCryptoServiceProvider csp = new TripleDESCryptoServiceProvider())
                    {
                        csp.GenerateIV();
                        IV = Convert.ToBase64String(csp.IV);
                        csp.GenerateKey();
                        Key = Convert.ToBase64String(csp.Key);
                    }
                    break;
                //可逆編碼(非對稱金鑰)
                case EncoderType.RSA:
                    using (RSACryptoServiceProvider csp = new RSACryptoServiceProvider())
                    {
                        IV = "";
                        Key = csp.ToXmlString(true);
                    }
                    break;
            }
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="type">編碼器種類</param>  
        /// <param name="encrypt">加密前字串</param>
        /// <returns>加密後字串</returns>
        public string Encrypt(EncoderType type, string encrypt)
        {
            string ret = "";
            byte[] inputByteArray = Encoding.UTF8.GetBytes(encrypt);

            switch (type)
            {
                //可逆編碼(對稱金鑰)
                case EncoderType.AES:
                    using (AesCryptoServiceProvider csp = new AesCryptoServiceProvider())
                    {
                        byte[] rgbKey = Convert.FromBase64String(Key);
                        byte[] rgbIV = Convert.FromBase64String(IV);

                        using (MemoryStream ms = new MemoryStream())
                        {
                            using (CryptoStream cs = new CryptoStream(ms, csp.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write))
                            {
                                cs.Write(inputByteArray, 0, inputByteArray.Length);
                                cs.FlushFinalBlock();
                                ret = Convert.ToBase64String(ms.ToArray());
                            }
                        }
                    }
                    break;
                case EncoderType.DES:
                    using (DESCryptoServiceProvider csp = new DESCryptoServiceProvider())
                    {   
                        byte[] rgbKey = Convert.FromBase64String(Key);
                        byte[] rgbIV = Convert.FromBase64String(IV);

                        using (MemoryStream ms = new MemoryStream())
                        {
                            using (CryptoStream cs = new CryptoStream(ms, csp.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write))
                            {
                                cs.Write(inputByteArray, 0, inputByteArray.Length);
                                cs.FlushFinalBlock();
                                ret = Convert.ToBase64String(ms.ToArray());
                            }
                        }
                    }
                    break;
                case EncoderType.RC2:
                    using (RC2CryptoServiceProvider csp = new RC2CryptoServiceProvider())
                    {
                        byte[] rgbKey = Convert.FromBase64String(Key);
                        byte[] rgbIV = Convert.FromBase64String(IV);

                        using (MemoryStream ms = new MemoryStream())
                        {
                            using (CryptoStream cs = new CryptoStream(ms, csp.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write))
                            {
                                cs.Write(inputByteArray, 0, inputByteArray.Length);
                                cs.FlushFinalBlock();
                                ret =  Convert.ToBase64String(ms.ToArray());
                            }
                        }
                    }
                    break;
                case EncoderType.TripleDES:
                    using (TripleDESCryptoServiceProvider csp = new TripleDESCryptoServiceProvider())
                    {
                        byte[] rgbKey = Convert.FromBase64String(Key);
                        byte[] rgbIV = Convert.FromBase64String(IV);

                        using (MemoryStream ms = new MemoryStream())
                        {
                            using (CryptoStream cs = new CryptoStream(ms, csp.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write))
                            {
                                cs.Write(inputByteArray, 0, inputByteArray.Length);
                                cs.FlushFinalBlock();
                                ret = Convert.ToBase64String(ms.ToArray());
                            }
                        }
                    }
                    break;
                //可逆編碼(非對稱金鑰)
                case EncoderType.RSA:
                    using (RSACryptoServiceProvider csp = new RSACryptoServiceProvider())
                    {
                        csp.FromXmlString(Key);
                        ret = Convert.ToBase64String(csp.Encrypt(inputByteArray, false));
                    }
                    break;
                //不可逆編碼(雜湊值)
                case EncoderType.MD5:
                    using (MD5CryptoServiceProvider csp = new MD5CryptoServiceProvider())
                    {
                        ret = BitConverter.ToString(csp.ComputeHash(inputByteArray)).Replace("-", string.Empty);  
                    }
                    break;
                case EncoderType.SHA1:
                    using (SHA1CryptoServiceProvider csp = new SHA1CryptoServiceProvider())
                    {
                        ret = BitConverter.ToString(csp.ComputeHash(inputByteArray)).Replace("-", string.Empty);
                    }
                    break;
                case EncoderType.SHA256:
                    using (SHA256CryptoServiceProvider csp = new SHA256CryptoServiceProvider())
                    {
                        ret = BitConverter.ToString(csp.ComputeHash(inputByteArray)).Replace("-", string.Empty);
                    }
                    break;
                case EncoderType.SHA384:
                    using (SHA384CryptoServiceProvider csp = new SHA384CryptoServiceProvider())
                    {
                        ret = BitConverter.ToString(csp.ComputeHash(inputByteArray)).Replace("-", string.Empty);
                    }
                    break;
                case EncoderType.SHA512:
                    using (SHA512CryptoServiceProvider csp = new SHA512CryptoServiceProvider())
                    {
                        ret = BitConverter.ToString(csp.ComputeHash(inputByteArray)).Replace("-", string.Empty);
                    }
                    break;
            }
            return ret;
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="type">編碼器種類</param>  
        /// <param name="decrypt">解密前字串</param>
        /// <returns>解密後字串</returns>
        public string Decrypt(EncoderType type, string decrypt)
        {
            string ret = "";
            byte[] inputByteArray = Convert.FromBase64String(decrypt);

            switch (type)
            {
                //可逆編碼(對稱金鑰)
                case EncoderType.AES:
                    using (AesCryptoServiceProvider csp = new AesCryptoServiceProvider())
                    {
                        byte[] rgbKey = Convert.FromBase64String(Key);
                        byte[] rgbIV = Convert.FromBase64String(IV);

                        using (MemoryStream ms = new MemoryStream())
                        {
                            using (CryptoStream cs = new CryptoStream(ms, csp.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write))
                            {
                                cs.Write(inputByteArray, 0, inputByteArray.Length);
                                cs.FlushFinalBlock();
                                ret = Encoding.UTF8.GetString(ms.ToArray());
                            }
                        }
                    }
                    break;
                case EncoderType.DES:
                    using (DESCryptoServiceProvider csp = new DESCryptoServiceProvider())
                    {
                        byte[] rgbKey = Convert.FromBase64String(Key);
                        byte[] rgbIV = Convert.FromBase64String(IV);

                        using (MemoryStream ms = new MemoryStream())
                        {
                            using (CryptoStream cs = new CryptoStream(ms, csp.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write))
                            {
                                cs.Write(inputByteArray, 0, inputByteArray.Length);
                                cs.FlushFinalBlock();
                                ret = Encoding.UTF8.GetString(ms.ToArray());
                            }
                        }
                    }
                    break;
                case EncoderType.RC2:
                    using (RC2CryptoServiceProvider csp = new RC2CryptoServiceProvider())
                    {    
                        byte[] rgbKey = Convert.FromBase64String(Key);
                        byte[] rgbIV = Convert.FromBase64String(IV);

                        using (MemoryStream ms = new MemoryStream())
                        {
                            using (CryptoStream cs = new CryptoStream(ms, csp.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write))
                            {
                                cs.Write(inputByteArray, 0, inputByteArray.Length);
                                cs.FlushFinalBlock();
                                ret = Encoding.UTF8.GetString(ms.ToArray());
                            }
                        }
                    }
                    break;
                case EncoderType.TripleDES:
                    using (TripleDESCryptoServiceProvider csp = new TripleDESCryptoServiceProvider())
                    {
                        byte[] rgbKey = Convert.FromBase64String(Key);
                        byte[] rgbIV = Convert.FromBase64String(IV);

                        using (MemoryStream ms = new MemoryStream())
                        {
                            using (CryptoStream cs = new CryptoStream(ms, csp.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write))
                            {
                                cs.Write(inputByteArray, 0, inputByteArray.Length);
                                cs.FlushFinalBlock();
                                ret = Encoding.UTF8.GetString(ms.ToArray());
                            }
                        }
                    }
                    break;
                //可逆編碼(非對稱金鑰)
                case EncoderType.RSA:
                    using (RSACryptoServiceProvider csp = new RSACryptoServiceProvider())
                    {
                        csp.FromXmlString(Key);
                        ret = Encoding.UTF8.GetString(csp.Decrypt(inputByteArray, false));
                    }
                    break;
            }
            return ret;
        }
    }
}

測試用
1.先新增一個C#的Windows Form應用程式的專案, 名稱為 Encoder
2.在在Form1上分別拉進
4個TextBox
5個Label
3個Button
1個ComboBox

檔案: Form1.Designer.cs

namespace Encoder
{
    partial class Form1
    {
        /// <summary>
        /// 設計工具所需的變數。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清除任何使用中的資源。
        /// </summary>
        /// <param name="disposing">如果應該處置 Managed 資源則為 true,否則為 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form 設計工具產生的程式碼

        /// <summary>
        /// 此為設計工具支援所需的方法 - 請勿使用程式碼編輯器
        /// 修改這個方法的內容。
        /// </summary>
        private void InitializeComponent()
        {
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.comboBox1 = new System.Windows.Forms.ComboBox();
            this.button3 = new System.Windows.Forms.Button();
            this.label4 = new System.Windows.Forms.Label();
            this.label5 = new System.Windows.Forms.Label();
            this.textBox3 = new System.Windows.Forms.TextBox();
            this.textBox4 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(-1, 21);
            this.textBox1.Multiline = true;
            this.textBox1.Name = "textBox1";
            this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            this.textBox1.Size = new System.Drawing.Size(400, 400);
            this.textBox1.TabIndex = 0;
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(-1, 3);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(41, 12);
            this.label1.TabIndex = 1;
            this.label1.Text = "加密前";
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(406, 100);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 2;
            this.button1.Text = "加密 ->";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(406, 130);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(75, 23);
            this.button2.TabIndex = 3;
            this.button2.Text = "<- 解密";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // textBox2
            // 
            this.textBox2.Location = new System.Drawing.Point(492, 21);
            this.textBox2.Multiline = true;
            this.textBox2.Name = "textBox2";
            this.textBox2.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            this.textBox2.Size = new System.Drawing.Size(400, 400);
            this.textBox2.TabIndex = 4;
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(492, 3);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(41, 12);
            this.label2.TabIndex = 5;
            this.label2.Text = "加密後";
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(13, 428);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(53, 12);
            this.label3.TabIndex = 6;
            this.label3.Text = "編碼方式";
            // 
            // comboBox1
            // 
            this.comboBox1.FormattingEnabled = true;
            this.comboBox1.Location = new System.Drawing.Point(72, 428);
            this.comboBox1.Name = "comboBox1";
            this.comboBox1.Size = new System.Drawing.Size(121, 20);
            this.comboBox1.TabIndex = 7;
            // 
            // button3
            // 
            this.button3.Location = new System.Drawing.Point(211, 428);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(75, 23);
            this.button3.TabIndex = 8;
            this.button3.Text = "產生新Key";
            this.button3.UseVisualStyleBackColor = true;
            this.button3.Click += new System.EventHandler(this.button3_Click);
            // 
            // label4
            // 
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(15, 459);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(24, 12);
            this.label4.TabIndex = 9;
            this.label4.Text = "Key";
            // 
            // label5
            // 
            this.label5.AutoSize = true;
            this.label5.Location = new System.Drawing.Point(497, 462);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(17, 12);
            this.label5.TabIndex = 10;
            this.label5.Text = "IV";
            // 
            // textBox3
            // 
            this.textBox3.Location = new System.Drawing.Point(72, 456);
            this.textBox3.Multiline = true;
            this.textBox3.Name = "textBox3";
            this.textBox3.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            this.textBox3.Size = new System.Drawing.Size(327, 66);
            this.textBox3.TabIndex = 11;
            // 
            // textBox4
            // 
            this.textBox4.Location = new System.Drawing.Point(520, 456);
            this.textBox4.Multiline = true;
            this.textBox4.Name = "textBox4";
            this.textBox4.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            this.textBox4.Size = new System.Drawing.Size(372, 66);
            this.textBox4.TabIndex = 12;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(904, 538);
            this.Controls.Add(this.textBox4);
            this.Controls.Add(this.textBox3);
            this.Controls.Add(this.label5);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.button3);
            this.Controls.Add(this.comboBox1);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.textBox2);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.textBox1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.TextBox textBox2;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.ComboBox comboBox1;
        private System.Windows.Forms.Button button3;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.TextBox textBox3;
        private System.Windows.Forms.TextBox textBox4;
    }
}

*檔案 Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
using Encoder.Security;

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

            string[] comboItems = { 
                                    //可逆編碼(對稱金鑰)
                                    "AES",
                                    "DES",
                                    "RC2",
                                    "TripleDES",

                                    //可逆編碼(非對稱金鑰)
                                    "RSA",

                                    //不可逆編碼(雜湊值)
                                    "MD5",
                                    "SHA1",
                                    "SHA256",
                                    "SHA384",
                                    "SHA512"
                                  };

            this.comboBox1.Items.Clear();
            foreach (string item in comboItems)
            {
                this.comboBox1.Items.Add(item);
            }
            this.comboBox1.SelectedIndex = 0;
        }

        Encoder.Security.Encoder encode = new Encoder.Security.Encoder();

        EncoderType GetEncoderType()
        {
            string str = this.comboBox1.Items[this.comboBox1.SelectedIndex].ToString();
            switch (str)
            {
                //可逆編碼(對稱金鑰)
                case "AES":         return EncoderType.AES;
                case "DES":         return EncoderType.DES;
                case "RC2":         return EncoderType.RC2;
                case "TripleDES":   return EncoderType.TripleDES;

                //可逆編碼(非對稱金鑰)
                case "RSA":         return EncoderType.RSA;

                //不可逆編碼(雜湊值)
                case "MD5":         return EncoderType.MD5;
                case "SHA1":        return EncoderType.SHA1;
                case "SHA256":      return EncoderType.SHA256;
                case "SHA384":      return EncoderType.SHA384;
                case "SHA512":      return EncoderType.SHA512;
                default:
                    {
                        this.comboBox1.SelectedIndex = 0;
                        return EncoderType.AES;
                    }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            EncoderType type = GetEncoderType();
            encode.Key = this.textBox3.Text;
            encode.IV = this.textBox4.Text;
            this.textBox2.Text = encode.Encrypt(type, this.textBox1.Text);            
        }

        private void button2_Click(object sender, EventArgs e)
        {
            EncoderType type = GetEncoderType();
            encode.Key = this.textBox3.Text;
            encode.IV = this.textBox4.Text;
            this.textBox1.Text = encode.Decrypt(type, this.textBox2.Text);     
        }

        private void button3_Click(object sender, EventArgs e)
        {
            EncoderType type = GetEncoderType();
            encode.GenerateKey(type);
            this.textBox3.Text= encode.Key;
            this.textBox4.Text = encode.IV;
        }
    }
}

3.最後, 建置 Encoder, 就這樣了


上一篇
C#應用(5)使用Eval
下一篇
C#應用(7)使用DirectShow.NET做轉檔工具
系列文
c#應用13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言