网上很多教程都是使用Rijndael类来加密解密,但是笔者使用这个类却不支持,难道是因为需要特殊的引用?
但是笔者参考官方文档找到加解密的方法,即是用AES类,效果一样
先上代码再说明:
/// <summary> /// AES加密 /// </summary> /// <param name="plainBytes">被加密的明文</param> /// <param name="bKey">密钥</param> /// <param name="bVector">向量</param> /// <returns>明文</returns> private static byte[] AESEncrypt(byte[] data, byte[] bKey, byte[] bVector) { Aes aesAlg = Aes.Create(); aesAlg.Key = bKey; aesAlg.IV = bVector; aesAlg.Padding = PaddingMode.Zeros; ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); return encryptor.TransformFinalBlock(data, 0, data.Length); }
这是加密用的函数
参数:
data数组,这是要加密的字节数组。如果是操作文件,建议循环调用函数,每次操作不要太大,这样可以显示进度,同时也防止文件过大消耗太多内存
这里特别注意的是,数组长度如果不是16的整数倍,则加密后自动在其后补充字节至16的整数倍(这里在解密部分说明原因)
bKey数组,这是加密使用的密码。这里需要特别注意,密码必须为128位或256位。其实112位也可以,但不普遍。建议128或256.
如果密码为128位,则加密方式自动调整为AES128。对于256位同理。如果不是特定的长度,则会产生异常
bVector数组,了解过Aes加密机制的就会知道,这作为加密的初始向量。
很多人不明白为什么要有这个参数,这不是多此一举吗?不,这很有用!
比如你加密一个字符串,如果密码相同,其结果即是确定的。这样会降低安全性,别人可能会通过比对的方法找出原信息。
但是如果你更改了初始向量,也就是AES每轮加密使用的密码都和以前的不同。这样加密后的结果也就不同。
根据我的理解,初始向量也就相当于AES的第二套密码
返回值:
这个没什么好说的,就是加密后的数据
下面再来看看解密操作
/// <summary> /// AES解密 /// </summary> /// <param name="encryptedBytes">被解密的密文</param> /// <param name="bKey">密钥</param> /// <param name="bVector">向量</param> /// <returns>明文</returns> private static byte[] AESDecrypt(byte[] data, byte[] bKey, byte[] bVector) { Aes aesAlg = Aes.Create(); aesAlg.Key = bKey; aesAlg.IV = bVector; aesAlg.Padding = PaddingMode.Zeros; ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); return decryptor.TransformFinalBlock(data, 0, data.Length); }
参数好理解,和加密用的参数相同。返回值为解密后的数据
但是这里还有一些要注意的地方:
前面加密提到,如果加密所用数组长度不是16的整数倍,则自动添加长度。
这是因为解密的data参数长度也必须为16的整数倍。加密结果是自动增加长度后的数据,则该数据可以直接作为解密函数的参数
笔者发现这个类,在控制台、WPF、WinForm、UWP都可以使用,比Rijndael更好用。
-------------------------------------------手动分界线--------------------------------------------
如果你想加密字符串,则只需调这两个函数用并做点转换即可
/// <summary> /// 加密 /// </summary> /// <param name="data"></param> /// <returns></returns> public static string AESEncrypt(string data) { return Encoding.Unicode.GetString(AESEncrypt(Encoding.Unicode.GetBytes(data))); } /// <summary> /// 解密 /// </summary> /// <param name="data"></param> /// <returns></returns> public static string AESDecrypt(string data) { return Encoding.Unicode.GetString(AESDecrypt(Encoding.Unicode.GetBytes(data))); }
是不是非常简单
如果你想加密文件,也只需只需调这两个函数用并做点转换即可(前提是小文件,如果是大文件,必须使用循环多次调用,否则内存消耗太高可能导致程序崩溃)
/// <summary> /// 加密文件 /// </summary> /// <param name="data"></param> /// <returns></returns> public static void AESEncryptFile(string path) { File.WriteAllBytes(path, AESEncrypt(File.ReadAllBytes(path))); } /// <summary> /// 解密文件 /// </summary> /// <param name="data"></param> /// <returns></returns> public static void AESDecryptFile(string path) { File.WriteAllBytes(path, AESDecrypt(File.ReadAllBytes(path))); }
如果还有疑问,欢迎联系wwh8797@qq.com
UWP应用“加解密”即主要是使用类似的方法。当然“加解密”也可加解密大文件,并支持批量操作,这就需要多次循环并调用加解密函数了
还有UWP应用“初心日记”,也是使用这个方法来加密用户的隐私数据,Aes加密在现阶段技术,几乎无解。所以“初心日记”能较好的保护用户隐私
读者可自行参考这两个软件