文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C#中如何实现AES算法加密

2023-07-05 06:21

关注

这篇文章主要介绍了C#中如何实现AES算法加密的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#中如何实现AES算法加密文章都会有所收获,下面我们一起来看看吧。

先上效果图

文件和加密文件之间的转换。

C#中如何实现AES算法加密

先添加辅助类

 public class AES_EnorDecrypt    {        //定义默认密钥        private static byte[] _aesKeyByte = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };        private static string _aesKeyStr = Encoding.UTF8.GetString(_aesKeyByte);        /// <summary>        /// 随机生成密钥,默认密钥长度为32,不足在加密时自动填充空格        /// </summary>        /// <param name="n">密钥长度</param>        /// <returns></returns>        public static string GetIv(int n)        {            string s = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";            char[] arrChar = new char[s.Length];            for (int i = 0; i < s.Length; i++)            {                arrChar[i] = Convert.ToChar(s.Substring(i, 1));            }            StringBuilder num = new StringBuilder();            Random rnd = new Random(DateTime.Now.Millisecond);            for (int i = 0; i < n; i++)            {                num.Append(arrChar[rnd.Next(0, arrChar.Length)].ToString());            }            _aesKeyByte = Encoding.UTF8.GetBytes(num.ToString());            return _aesKeyStr = Encoding.UTF8.GetString(_aesKeyByte);        }        /// <summary>        /// AES加密,针对文本类文件        /// </summary>        /// <param name="Data">被加密的明文</param>        /// <param name="Key">密钥</param>        /// <param name="Vector">密钥向量</param>        /// <returns>密文</returns>        public static string AESEncrypt(string Data, string Key, string Vector)        {            byte[] plainBytes = Encoding.UTF8.GetBytes(Data);            byte[] bKey = new byte[32];            Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);            byte[] bVector = new byte[16];            Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);            byte[] Cryptograph = null;//加密后的密文            Rijndael Aes = Rijndael.Create();            try            {                using (MemoryStream Memory = new MemoryStream())                {                    //把内存流对象包装成加密流对象                    using (CryptoStream Encryptor = new CryptoStream(Memory, Aes.CreateEncryptor(bKey, bVector), CryptoStreamMode.Write))                    {                        Encryptor.Write(plainBytes, 0, plainBytes.Length);                        Encryptor.FlushFinalBlock();                        Cryptograph = Memory.ToArray();                    }                }            }            catch            {                Cryptograph = null;            }            return Convert.ToBase64String(Cryptograph);        }        /// <summary>        /// AES加密,任意文件        /// </summary>        /// <param name="Data">被加密的明文</param>        /// <param name="Key">密钥</param>        /// <param name="Vector">密钥向量</param>        /// <returns>密文</returns>        public static byte[] AESEncrypt(byte[] Data, string Key, string Vector)        {            byte[] bKey = new byte[32];            Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);            byte[] bVector = new byte[16];            Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);            byte[] Cryptograph = null;//加密后的密文            Rijndael Aes = Rijndael.Create();            try            {                using (MemoryStream Memory = new MemoryStream())                {                    //把内存流对象包装成加密流对象                    using (CryptoStream Encryptor = new CryptoStream(Memory, Aes.CreateEncryptor(bKey, bVector), CryptoStreamMode.Write))                    {                        Encryptor.Write(Data, 0, Data.Length);                        Encryptor.FlushFinalBlock();                        Cryptograph = Memory.ToArray();                    }                }            }            catch            {                Cryptograph = null;            }            return Cryptograph;        }        /// <summary>        /// AES解密,针对文本文件        /// </summary>        /// <param name="Data">被解密的密文</param>        /// <param name="Key">密钥</param>        /// <param name="Vector">密钥向量</param>        /// <returns>明文</returns>        public static string AESDecrypt(string Data, string Key, string Vector)        {            byte[] encryptedBytes = Convert.FromBase64String(Data);            byte[] bKey = new byte[32];            Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);            byte[] bVector = new byte[16];            Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);            byte[] original = null;//解密后的明文            Rijndael Aes = Rijndael.Create();            try            {                using (MemoryStream Memory = new MemoryStream(encryptedBytes))                {                    //把内存流对象包装成加密对象                    using (CryptoStream Decryptor = new CryptoStream(Memory, Aes.CreateDecryptor(bKey, bVector), CryptoStreamMode.Read))                    {                        //明文存储区                        using (MemoryStream originalMemory = new MemoryStream())                        {                            byte[] Buffer = new byte[1024];                            int readBytes = 0;                            while ((readBytes = Decryptor.Read(Buffer, 0, Buffer.Length)) > 0)                            {                                originalMemory.Write(Buffer, 0, readBytes);                            }                            original = originalMemory.ToArray();                        }                    }                }            }            catch            {                original = null;            }            return Encoding.UTF8.GetString(original);        }        /// <summary>        /// AES解密,任意文件        /// </summary>        /// <param name="Data">被解密的密文</param>        /// <param name="Key">密钥</param>        /// <param name="Vector">密钥向量</param>        /// <returns>明文</returns>        public static byte[] AESDecrypt(byte[] Data, string Key, string Vector)        {            byte[] bKey = new byte[32];            Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);            byte[] bVector = new byte[16];            Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);            byte[] original = null;//解密后的明文            Rijndael Aes = Rijndael.Create();            try            {                using (MemoryStream Memory = new MemoryStream(Data))                {                    //把内存流对象包装成加密对象                    using (CryptoStream Decryptor = new CryptoStream(Memory, Aes.CreateDecryptor(bKey, bVector), CryptoStreamMode.Read))                    {                        //明文存储区                        using (MemoryStream originalMemory = new MemoryStream())                        {                            byte[] Buffer = new byte[1024];                            int readBytes = 0;                            while ((readBytes = Decryptor.Read(Buffer, 0, Buffer.Length)) > 0)                            {                                originalMemory.Write(Buffer, 0, readBytes);                            }                            original = originalMemory.ToArray();                        }                    }                }            }            catch            {                original = null;            }            return original;        }    }

AES是块加密,块的长度是16字节,如果原文不到16的字节,就会进行填充至16个字节。

开始实现

界面布局

C#中如何实现AES算法加密

textbox1为文件位置,textbox2为密码。

C#中如何实现AES算法加密

C#中如何实现AES算法加密

C#中如何实现AES算法加密

设置好后

public partial class FormAes : Form    {        #region 属性        private static string _aesKeyVector = "q2T_=R/*33vc";        #endregion        public FormAes()        {            InitializeComponent();        }        /// <summary>        /// 选择文件        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void textBox1_Click(object sender, EventArgs e)        {            OpenFileDialog dialog = new OpenFileDialog();            dialog.Multiselect = true;//该值确定是否可以选择多个文件            dialog.Title = "请选择文件夹";            dialog.Filter = "所有文件(*.*)|*.*";            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)            {                textBox1.Text = dialog.FileName;            }        }        /// <summary>        /// 加密        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void button1_Click(object sender, EventArgs e)        {            if (string.IsNullOrWhiteSpace(textBox1.Text.Trim()) || string.IsNullOrWhiteSpace(textBox2.Text.Trim()))                return;            backgroundWorker1.RunWorkerAsync();        }        /// <summary>        /// 解密        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void button2_Click(object sender, EventArgs e)        {            if (string.IsNullOrWhiteSpace(textBox1.Text.Trim()) || string.IsNullOrWhiteSpace(textBox2.Text.Trim()))                return;            backgroundWorker2.RunWorkerAsync();        }        /// <summary>        /// 后台线程执行的方法        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)        {                       string KeyVector = _aesKeyVector;//密钥向量            string path = Path.GetDirectoryName(textBox1.Text);            string name = Path.GetFileName(textBox1.Text);            name += ".En";            #region   加密            FileStream sr = new FileStream(textBox1.Text, FileMode.Open, FileAccess.Read);            FileStream sw = new FileStream(path + "\\" + name, FileMode.Create, FileAccess.Write);            if (sr.Length > 50 * 1024 * 1024)//如果文件大于50M,采取分块加密,按50MB读写            {                byte[] mybyte = new byte[52428800];//每50MB加密一次                                  int numBytesRead = 52428800;//每次加密的流大小                long leftBytes = sr.Length;//剩余需要加密的流大小                long readBytes = 0;//已经读取的流大小                //每50MB加密后会变成50MB+16B                byte[] encrpy = new byte[52428816];                while (true)                {                    if (leftBytes > numBytesRead)                    {                        sr.Read(mybyte, 0, mybyte.Length);                        encrpy = AES_EnorDecrypt.AESEncrypt(mybyte, textBox2.Text, KeyVector);                        sw.Write(encrpy, 0, encrpy.Length);                        leftBytes -= numBytesRead;                        readBytes += numBytesRead;                        backgroundWorker1.ReportProgress((int)(readBytes * 100 / sr.Length));                    }                    else//重新设定读取流大小,避免最后多余空值                    {                        byte[] newByte = new byte[leftBytes];                        sr.Read(newByte, 0, newByte.Length);                        byte[] newWriteByte;                        newWriteByte = AES_EnorDecrypt.AESEncrypt(newByte, textBox2.Text, KeyVector);                        sw.Write(newWriteByte, 0, newWriteByte.Length);                        readBytes += leftBytes;                        backgroundWorker1.ReportProgress((int)(readBytes * 100 / sr.Length));                        break;                    }                }            }            else            {                byte[] mybyte = new byte[sr.Length];                sr.Read(mybyte, 0, (int)sr.Length);                mybyte = AES_EnorDecrypt.AESEncrypt(mybyte, textBox2.Text, KeyVector);                sw.Write(mybyte, 0, mybyte.Length);                backgroundWorker1.ReportProgress(100);            }            sr.Close();            sw.Close();            #endregion        }               private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)        {            progressBar1.Value = e.ProgressPercentage;        }        /// <summary>        /// 执行完成时触发        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)        {            MessageBox.Show("加密成功!");        }        /// <summary>        /// 后台线程执行的方法        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)        {            try            {                string KeyVector = _aesKeyVector;//密钥向量                string path = Path.GetDirectoryName(textBox1.Text);                string name = Path.GetFileName(textBox1.Text);                if (name.EndsWith(".En"))                {                    name = name.Remove(name.Length - 3, 3);                }                #region  解密                FileStream sr = new FileStream(textBox1.Text, FileMode.Open, FileAccess.Read);                FileStream sw = new FileStream(path + "\\" + name, FileMode.Create, FileAccess.Write);                if (sr.Length > 50 * 1024 * 1024)//如果文件大于50M,采取分块解密,按50MB读写                {                    byte[] mybyte = new byte[52428816];//解密缓冲区50MB+16B                    byte[] decrpt = new byte[52428800];//解密后的50MB                    int numBytesRead = 52428816;//每次解密的流大小                    long leftBytes = sr.Length;//剩余需要解密的流大小                    long readBytes = 0;//已经读取的流大小                    try                    {                        while (true)                        {                            if (leftBytes > numBytesRead)                            {                                sr.Read(mybyte, 0, mybyte.Length);                                decrpt = AES_EnorDecrypt.AESDecrypt(mybyte, textBox2.Text, KeyVector);                                sw.Write(decrpt, 0, decrpt.Length);                                leftBytes -= numBytesRead;                                readBytes += numBytesRead;                                backgroundWorker2.ReportProgress((int)(readBytes * 100 / sr.Length));                            }                            else//重新设定读取流大小,避免最后多余空值                            {                                byte[] newByte = new byte[leftBytes];                                sr.Read(newByte, 0, newByte.Length);                                byte[] newWriteByte;                                newWriteByte = AES_EnorDecrypt.AESDecrypt(newByte, textBox2.Text, KeyVector);                                sw.Write(newWriteByte, 0, newWriteByte.Length);                                readBytes += leftBytes;                                backgroundWorker2.ReportProgress((int)(readBytes * 100 / sr.Length));                                break;                            }                        }                    }                    catch                    {                        sr.Close();                        sw.Close();                        File.Delete(path + "\\" + name);                        e.Cancel = true;                    }                    sr.Close();                    sw.Close();                }                else                {                    byte[] mybyte = new byte[(int)sr.Length];                    sr.Read(mybyte, 0, (int)sr.Length);                    try                    {                        mybyte = AES_EnorDecrypt.AESDecrypt(mybyte, textBox2.Text, KeyVector);                        sw.Write(mybyte, 0, mybyte.Length);                        backgroundWorker2.ReportProgress(100);                    }                    catch                    {                        sr.Close();                        sw.Close();                        File.Delete(path + "\\" + name);                        e.Cancel = true;                    }                    sr.Close();                    sw.Close();                }                #endregion            }            catch            {                e.Cancel = true;            }        }        private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)        {           progressBar1.Value = e.ProgressPercentage;        }        /// <summary>        /// 执行完成时触发        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)        {            if (e.Cancelled)            {               MessageBox.Show("解密失败\n密码错误或加密文件被篡改,无法解密");                            }            else            {                MessageBox.Show("解密成功!");            }        }       }

关于“C#中如何实现AES算法加密”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“C#中如何实现AES算法加密”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯