c#如何实现加密解密AES字节数组

  介绍

这期内容当中小编将会给大家带来有关c#如何实现加密解密AES字节数组,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

AES类时微软MSDN中最常用的加密类
1,输入一个字节数组,经AES加密后,直接输出加密后的字节数组。
2,输入一个加密后的字节数组,经AES解密后,直接输出原字节数组。

对于我这个十八流业余爱好者来说,AES我是以用为主的,所以具体的AES是怎么运算的,我其实并不关心,我更关心的是AES的处理流程。结果恰恰这一方面,网上的信息差强人意,看了网上不少的帖子,但感觉都没有说完整说透,而且很多帖子有错误。

因此,我自己绘制了一张此种方式下的流程图:

 c #如何实现加密解密AES字节数组

按照此流程图进行了核心代码的编写,验证方法AesCoreSingleTest既是依照此流程的产物,实例化类AesCoreSingle后调用此方法即可验证。

至于类中的异步方法EnOrDecryptFileAsync,则是专门用于文件加解密的处理,此异步方法参考自《c# 6.0学习笔记》(周家安著)最后的示例,这本书写得真棒。

使用系统;
  使用System.Collections.Generic;
  使用先;
  使用来;
  使用System.Security.Cryptography;
  使用text;
  使用System.Threading;
  使用System.Threading.Tasks;
  使用System.Windows;
  
  名称空间AesSingleFile
  {
  类AesCoreSingle
  {///& lt; summary>///使用用户口令,生成符合AES标准的密钥和iv。///& lt;/summary>///& lt;参数name=皃assword"在用户输入的口令& lt;/param>///& lt; returns>返回包含密钥和向量的元组& lt;/returns>
  私人(byte[]键,byte[](四)GenerateKeyAndIV(字符串密码)
  {
  byte[]键=新字节[32];
  第四byte[]=[16]新字节;
  byte[]散列=违约;
  如果(string.IsNullOrWhiteSpace(密码))
  把新的ArgumentException(“必须输入口令!“);
  使用(SHA384沙=SHA384.Create ())
  {
  缓冲区byte []=Encoding.UTF8.GetBytes(密码);
  散列=sha.ComputeHash(缓冲);
  }//用SHA384的原因:生成的384位哈希值正好被分成两段使用。(32 + 16)* 8=384。
  数组中。复制(散列,0键,0,32);//生成256位密钥(32 * 8=256)
  数组中。副本(散列,32岁,四0 16);//生成128位向量(16 * 8=128)
  返回(关键:键,四:IV);
  }
  
  公共byte [] EncryptByte (byte[]缓冲区,字符串密码)
  {
  byte[]加密;
  使用(Aes Aes=Aes.Create ())
  {//设定密钥和向量
  (aes。键,aes.IV)=GenerateKeyAndIV(密码);//设定运算模式和填充模式
  aes。模式=CipherMode.CBC;//默认
  aes。填充=PaddingMode.PKCS7;//默认//创建加密器对象(加解密方法不同处仅仅这一句话)
  var加密机=aes.CreateEncryptor (aes。键,aes.IV);
  使用(MemoryStream msEncrypt=new MemoryStream ())
  {
  使用(CryptoStream csEncrypt=new CryptoStream(加密机,msEncrypt CryptoStreamMode.Write))//选择写模式
  {
  csEncrypt。写(缓冲区,0,buffer.Length);//对原数组加密并写入流中
  csEncrypt.FlushFinalBlock();//使用写模式需要此句,但阅读模式必须要有。
  加密=msEncrypt.ToArray();//从流中写入数组(加密之后,数组变长,详见方法AesCoreSingleTest内容)
  }
  }
  }
  返回加密;
  }
  公共byte [] DecryptByte (byte[]缓冲区,字符串密码)
  {
  byte[]解密;
  使用(Aes Aes=Aes.Create ())
  {//设定密钥和向量
  (aes。键,aes.IV)=GenerateKeyAndIV(密码);//设定运算模式和填充模式
  aes。模式=CipherMode.CBC;//默认
  aes。填充=PaddingMode.PKCS7;//默认//创建解密器对象(加解密方法不同处仅仅这一句话)
  var decryptor=aes.CreateDecryptor (aes。键,aes.IV);
  使用(MemoryStream msDecrypt=new MemoryStream(缓冲))
  {
  使用(CryptoStream csDecrypt=new CryptoStream (msDecrypt、decryptor CryptoStreamMode.Read))//选择读模式
  {
  byte [] buffer_T=新字节(buffer.Length);/* - s1:创建临时数组,用于包含可用字节+无用字节——*/int i=csDecrypt。读(buffer_T 0 buffer.Length);/* - s2:对加密数组进行解密,并通过我确定实际多少字节可用——*///csDecrypt.FlushFinalBlock();//使用阅读模式不能有此句,但写模式必须要有。
  
  解密=new byte [];/*——s3:创建只容纳可用字节的数组——*/数组中。复制(buffer_T 0解密0 i);/*——s4:从bufferT拷贝出可用字节到解密——*/}
  }
  返回解密;
  }
  }
  公共byte [] EnOrDecryptByte (byte[]缓冲区,字符串密码,ActionDirection方向)
  {
  如果(缓冲==null)
  把新的ArgumentNullException(“缓冲区为空“);
  如果密码==null | |密码==啊?
  把新ArgumentNullException(“密码为空“);
  如果==ActionDirection.EnCrypt(方向)
  返回EncryptByte(缓冲区,密码);
  其他的
  返回DecryptByte(缓冲区,密码);
  }
  公共enum ActionDirection//该枚举说明是加密还是解密
  {//加密,加密//解密解密
  }
  公共静态孔隙AesCoreSingleTest (s_in的字符串,字符串密码)//验证加密解密模块正确性方法
  {
  缓冲区byte []=Encoding.UTF8.GetBytes (s_in);
  AesCoreSingle aesCore=new AesCoreSingle ();
  byte [] buffer_ed=aesCore。EncryptByte(缓冲、密码);
  byte [] buffer_ed2=aesCore。DecryptByte (buffer_ed、密码);
  字符串s=Encoding.UTF8.GetString (buffer_ed2);
  字符串s2=跋铝凶址甛 n"+ s + & # 39; \ n # 39;+ $“原缓冲区长度→{缓冲区。长度},加密后buffer_ed长度→{buffer_ed。长度},解密后buffer_ed2长度→{buffer_ed2.Length}“;
  MessageBox.Show (s2);/*字符串在加密前后的变化(默认CipherMode。CBC运算模式,PaddingMode.PKCS7填充模式)
  * 1,如果数组长度为16的倍数,则加密后的数组长度=原长度+ 16
  如对于下列字符串
  D: \ \ \文件管理员用户- DOpus配置- 2020 - 06 - 301. -台籍干部
  使用UTF8编码转化为字节数组后,
  64年原缓冲区→加密后buffer_ed→80年,解密后buffer_ed2→64
  * 2,如果数组长度不为16的倍数,则加密后的数组长度=16倍数向上取整
  如对于下列字符串
  D: \用户\ \ cc_20200630_113921.reg文档
  使用UTF8编码转化为字节数组后
  原缓冲区→40加密后buffer_ed→48岁的解密后buffer_ed2→40
  参考文献:
  1 -《AES补位填充PaddingMode.Zeros模式》http://blog.chinaunix.net/uid - 29641438 - id - 5786927. - html
  2 -《关于PKCS5Padding与PKCS7Padding的区别》https://www.cnblogs.com/midea0978/articles/1437257.html
  3 -《aes - 128欧洲央行加密有感》http://blog.sina.com.cn/s/blog_60cf051301015orf.html
  */}/* * * - - -声的时候触发明对象——* * */的时候触发私人cts;//使用System.Threading引用
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null

c#如何实现加密解密AES字节数组