命名空间引用
using System.IO;//内存流读写方法调用
using System.Security.Cryptography;//加密解密方法调用
加密方法
String key = "12345678";//定义加密解密所用密钥。
Console.WriteLine("请输入要加密的字符串:");
String str = Console.ReadLine();//读取要加密的字符串
DESCryptoServiceProvider des = new DESCryptoServiceProvider();//实例化加密类对象
byte[] arr_key = Encoding.UTF8.GetBytes(key.Substring(0, 8));//定义字节数组用来存放密钥 GetBytes方法用于将字符串中所有字节编码为一个字节序列
////!!!DES加密key位数只能是64位,即8字节
////注意这里用的编码用当前默认编码方式,不确定就用Default
byte[] arr_str = Encoding.UTF8.GetBytes(str);//定义字节数组存放要加密的字符串
MemoryStream ms = new MemoryStream();//实例化内存流对象
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(arr_key, arr_key), CryptoStreamMode.Write);//创建加密流对象,参数 内存流/初始化向量IV/加密流模式
cs.Write(arr_str, 0, arr_str.Length);//需加密字节数组/offset/length,此方法将length个字节从 arr_str 复制到当前流。0是偏移量offset,即从指定index开始复制。
cs.Close();
string str_des = Convert.ToBase64String(ms.ToArray());
Console.WriteLine("加密后的字符串:");
Console.WriteLine(str_des);
对于初始化向量iv
简易理解,为了防止想同的明文加密后密文仍然一致,需要在加密算法中引入变化的量,由此引入向量的,用户指定向量初始值,加密算法自动计算出其后续值,加密时每部分混合密钥和当前向量值进行加密,由此相同的明文加密后的密文会不一致,提升安全性。
加密流程总结
在加密方法加密字符串、密钥、初始向量均需外部传入。首先将三部分转化为字符数组,然后实例化加密类对象,实例化内存流对象,实例化加密流对象(CryptoStream 的任何加密对象可以和实现 和Stream 的任何对象链接起来,因此加密对象的流式处理输出可以作为另一个对象的输入,通俗理解即即内存流作为加密流的输出对象),加密流读取字节数组并加密到流,随后将加密后的流输出到内存流并清空缓冲区。注意此处需要执行只有调用FlushFinalBlock后,数据才被真正写入内存流。举个例子:
解密方法需要用到 加密字符串、密钥、初始化向量。
//解密
ms = new MemoryStream();
byte[] arr_des = Convert.FromBase64String(str_des);//注意这里仍要将密文作为base64字符串处理获得数组,否则报错
//byte[] arr_des = Encoding.UTF8.GetBytes(str_des);//不可行,将加密方法中ms的字符数组转为utf-8也不行
des = new DESCryptoServiceProvider();//解密方法定义加密对象
cs = new CryptoStream(ms, des.CreateDecryptor(arr_key, arr_key), CryptoStreamMode.Write);
cs.Write(arr_des, 0, arr_des.Length);
cs.FlushFinalBlock();
cs.Close();
Encoding.UTF8.GetString(ms.ToArray());//此处与加密前编码一致
Console.WriteLine("解密后的字符串:");
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));