广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C#中实现AES算法加密解读
  • 603
分享到

C#中实现AES算法加密解读

C#AES算法加密AES算法加密C#AES加密 2023-02-26 14:02:45 603人浏览 安东尼
摘要

目录先上效果图先添加辅助类开始实现总结先上效果图 文件和加密文件之间的转换。 先添加辅助类 public class AES_EnorDecrypt {

先上效果图

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

先添加辅助类

 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个字节。

开始实现

界面布局

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

设置好后

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("解密成功!");
            }
        }   
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: C#中实现AES算法加密解读

本文链接: https://www.lsjlt.com/news/197579.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C#中实现AES算法加密解读
    目录先上效果图先添加辅助类开始实现总结先上效果图 文件和加密文件之间的转换。 先添加辅助类 public class AES_EnorDecrypt { ...
    99+
    2023-02-26
    C# AES算法加密 AES算法加密 C# AES加密
  • C#加解密之AES算法的实现
    目录实现功能开发环境实现代码实现效果从这一篇开始呢,写一下常用的一些加解密方式。一般我们来说呢,对于加密,我们分为可逆和不可逆。可逆加密又可分为对称加密(AES、DES等)和非对称加...
    99+
    2022-11-13
  • C#中如何实现AES算法加密
    这篇文章主要介绍了C#中如何实现AES算法加密的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#中如何实现AES算法加密文章都会有所收获,下面我们一起来看看吧。先上效果图文件和加密文件之间的转换。先添加辅助类&...
    99+
    2023-07-05
  • python实现AES算法及AES-CFB8加解密源码
    目录Python实现AES算法生成轮密钥加密解密完整代码如下测试测试程序Python实现AES-CFB8加解密Python实现AES算法 密码学课程老师留的作业,我觉得用python...
    99+
    2022-11-13
  • ASP.NETCore实现AES-GCM加密算法
    传统的加密算法中,一个主要的问题是无法确认密钥或密文的有效性,也就是说,当密钥或密文错误时,照样能解密,但不报错。还需要我们制定一个一个原文的校验算法。 为了简化这个过程,一种方式是...
    99+
    2022-11-13
  • Golang实现AES对称加密算法实例详解
    目录前言前置知识生成随机数生成随机字符串加密和解密加密解密总结前言 安全总是相对的,对于敏感数据最好要有一定保护措施,尤其是在线数据,通过加密可转换信息为编码,从而防止非法获取。对开...
    99+
    2023-02-21
    golang 对称加密 go语言aes加密 对称加密 aes
  • jquery实现aes加密解密
    随着互联网技术的发展,网络安全问题变得越来越突出。许多网站都要求用户输入敏感信息,如密码等。这些信息往往需要进行加密处理,以保证安全性。AES(Advanced Encryption Standard)是一种流行的加密算法,具有高效、安全、...
    99+
    2023-05-24
  • AES加密解密python实现
    1.前言         关于现代密码学算法,可以查看以下博客全面了解 CISSP考试要求里的“应用密码学”内容辅助记忆趣味串讲_晓翔仔的博客-CSDN博客         AES的细节知识,可以查阅 AES加密算法的详细介绍与实现_Tim...
    99+
    2023-09-20
    python 开发语言 密码学 非对称加密 AES
  • JAVA实现AES加密,解密
    java提供了加解密工具,可以将字节转成加密字节. 因此在加解密前需要对内容进行转换. 一般情况我们希望以字符串的形式展示加密串 可以将byte[] 转换为base64字符串 也可以转换为16进制字符串 这里提供两个工具类 加密串为base...
    99+
    2023-08-24
    java 数据库 mysql
  • Java实现加密(一)AES加解密
    目录 1.背景知识2.AES简介3.AES的加密过程(AES处理单位:字节)4.Java实现4.1 生成密钥和偏移量4.2 AESUtil.java 源码4.3 执行结果4.4 线上验证 1.背景知识 在密码学中,加...
    99+
    2023-08-18
    java
  • Golang如何实现AES对称加密算法
    本篇内容主要讲解“Golang如何实现AES对称加密算法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Golang如何实现AES对称加密算法”吧!前置知识在正式学习加密解密之前,首先看看如何生成...
    99+
    2023-07-05
  • Java AES加密解密的简单实现方法
    废话不多说,直接上代码package com.mstf.aes; import java.io.UnsupportedEncodingException;import java.security.InvalidKeyException;im...
    99+
    2023-05-31
    java rsa 加密
  • Rust实现AES加解密详解
    目录一、选择使用 rust-crypto二、Cargo.toml 文件三、工具类1、加密2、解密3、测试样例一、选择使用 rust-crypto rust-crypto 官方相关站点...
    99+
    2022-11-13
    Rust AES加解密 Rust 加密 Rust 解密
  • 使用Java实现加密之AES加解密
    目录1.背景知识2.AES简介3.AES的加密过程(AES处理单位:字节)4.Java实现4.1 生成密钥和偏移量4.2 AESUtil.java 源码4.3 执行结果4.4 线上验...
    99+
    2023-05-18
    Java AES AES 加解密
  • C#利用异或算法实现加密解密
    目录实践过程效果代码实践过程 效果 代码 public partial class Form1 : Form { public Form1() { ...
    99+
    2023-01-03
    C#异或算法实现加密解密 C# 异或算法 C# 加密解密
  • C#加解密之DES算法的实现
    目录前言实现功能开发环境实现代码实现效果前言 说完了对称加密中的AES,这一篇再来介绍下DES。 加解密原理什么的就不介绍了,大家可以自行百度(主要我也不太明白,也不需要太明白),大...
    99+
    2022-11-13
  • golang实现aes-cbc-256加密解密功能
    目录我为什么吃撑了要实现go的aes-cbc-256加密解密功能?1:面临两个问题1:go秘钥长度必须是16/24/322:go根本不支持256位的aes-cbc加密解密3:想用go...
    99+
    2023-05-18
    go aes加密解密 go 256加密解密
  • php中如何实现Aes加密
    这期内容当中小编将会给大家带来有关php中如何实现Aes加密,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在项目中,尤其是pc端的时候,我们在用户登录后会给前端返回一个标识,来判断用户是否登录,这个标识大...
    99+
    2023-06-20
  • golang常用加密解密算法总结(AES、DES、RSA、Sha1、MD5)
    目录关于加密解密AESDESRSAMD5Sha1Base64在项目开发过程中,当操作一些用户的隐私信息,诸如密码、帐户密钥等数据时,往往需要加密后可以在网上传输。这时,需要一些高效地...
    99+
    2022-11-13
  • Java 实现 AES 加密和解密完整示例
    1、简介 AES,全称为 Advanced Encryption Standard,是一种分组密码算法,用于保护敏感数据的传输和存储。AES 分为 128 位和 256 位两种密钥长度,可以对数据进行...
    99+
    2023-09-09
    java aes AES 加密 解密
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作