首先.NET中的ICryptoTransform是单向的,也就是只能从一个状态将数据转化成另一个状态,反之是不可以的。当然手动 操作ICryptoTransform还是比较繁琐的,通过CryptoStream可以更轻松地操作一个ICryptoTransform。由于 ICryptoTransform是单向的,所以加密解密这两个过程就需要两个ICryptoTransform,这个通过 SymmetricAlgorithm类的CreateEncryptor和CreateDecryptor方法来创建。而用CryptoStream操 作这两个ICryptoTransform时,往往加密就是用CryptoStreamMode.Write,解密则用Read,这个从名称上也是合情合 理的,但是其实CryptoStream的操作模式不是局限于这样的。
关于ICryptoTransform和CryptoStream的关系模式,可以看这个图:
其实所谓的Read和Write仅仅是把ICryptoTransform操作的两个数据状态换了个位置,最终操作仍然是将ICryptoTransform的源数据转换成目标数据(单向),只不过不同的模式操作不一样。
比如我们先使用CryptoStreamMode.Write来加密:
//+ using System.IO;
//+ using System.Security.Cryptography;
staticvoid Main()
{
using (var aes =Aes.Create())
{
var data =Encoding.Unicode.GetBytes("Mgen!");
Console.WriteLine(BitConverter.ToString(Encrypt_Write(aes.CreateEncryptor(), data).ToArray()));
}
}
staticMemoryStream Encrypt_Write(ICryptoTransform ict, byte[] data)
{
using (var ms =newMemoryStream())
using (var cstream =newCryptoStream(ms, ict, CryptoStreamMode.Write))
{
cstream.Write(data, 0, data.Length);
return ms;
}
}
用CryptoStreamMode.Read也可以完成加密:
//+ using System.IO;
//+ using System.Security.Cryptography;
staticvoid Main()
{
using (var aes =Aes.Create())
{
var data =Encoding.Unicode.GetBytes("Mgen!");
Console.WriteLine(BitConverter.ToString(Encrypt_Read(aes.CreateEncryptor(), data).ToArray()));
}
}
staticMemoryStream Encrypt_Read(ICryptoTransform ict, byte[] data)
{
using (var ms =newMemoryStream(data))
using (var cstream =newCryptoStream(ms, ict, CryptoStreamMode.Read))
using (var destMs =newMemoryStream())
{
byte[] buffer =newbyte[100];
int readLen;
while ((readLen = cstream.Read(buffer, 0, 100)) >0)
destMs.Write(buffer, 0, readLen);
return destMs;
}
}
两者都会成功加密数据,并输入:
DB-76-CA-5F-62-2C-59-C1-91-48-79-9F-10-B9-8E-2D
上面只讲了加密,解密也是完全一样的,CryptoStreamMode.Write或Read都可以解密!
转自:http://www.mgenware.com/blog/?p=96