TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider(); byte[] keyArray = tDESalg.Key; byte[] IVArray = tDESalg.IV;
生成的key和IV在加密过程和解密过程都要使用。
2、 字符串明文转成某一代码页对应的编码字节流
待加密的数据可能有两种形式,一种是二进制的数据,本身就是一组字节流,这样的数据可以跳过这一步,直接进入加密步骤。还有一种情况是字符串数据,字符串中同样的字符使用不同的代码页会生成不同的字节码,所以从字符串到字节流的转换是需要指定使用何种编码的。在解密之后,要从字节流转换到字符串就要使用相同的代码页解码,否则就会出现乱码。
// 待加密的字符串
string plainTextString = "Here is some data to encrypt. 这里是一些要加密的数据。";
// 使用utf-8编码(也可以使用其它的编码)
Encoding sEncoding = Encoding.GetEncoding("utf-8");
// 把字符串明文转换成utf-8编码的字节流
byte[] plainTextArray = sEncoding.GetBytes(plainTextString);
3、 加密操作
加密的原料是明文字节流,TripleDES算法对字节流进行加密,返回的是加密后的字节流。同时要给定加密使用的key和IV。
// 把字符串明文转换成utf-8编码的字节流
byte[] plainTextArray = sEncoding.GetBytes(plainTextString); public static byte[] EncryptString(byte[] plainTextArray, byte[] Key, byte[] IV) { // 建立一个MemoryStream,这里面存放加密后的数据流 MemoryStream mStream = new MemoryStream(); // 使用MemoryStream 和key、IV新建一个CryptoStream 对象 CryptoStream cStream = new CryptoStream(mStream, new TripleDESCryptoServiceProvider().CreateEncryptor(Key, IV), CryptoStreamMode.Write); // 将加密后的字节流写入到MemoryStream cStream.Write(plainTextArray, 0, plainTextArray.Length); //把缓冲区中的最后状态更新到MemoryStream,并清除cStream的缓存区 cStream.FlushFinalBlock(); // 把解密后的数据流转成字节流 byte[] ret = mStream.ToArray(); // 关闭两个streams. cStream.Close(); mStream.Close(); return ret; }
4、 解密操作
解密操作解密上面步骤生成的密文byte[],需要使用到加密步骤使用的同一组Key和IV。
// 调用解密方法,返回已解密数据的byte[]
byte[] finalPlainTextArray = DecryptTextFromMemory(Data, keyArray, IVArray); public static byte[] DecryptTextFromMemory(byte[] EncryptedDataArray, byte[] Key, byte[] IV) { // 建立一个MemoryStream,这里面存放加密后的数据流 MemoryStream msDecrypt = new MemoryStream(EncryptedDataArray); // 使用MemoryStream 和key、IV新建一个CryptoStream 对象 CryptoStream csDecrypt = new CryptoStream(msDecrypt, new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV), CryptoStreamMode.Read); // 根据密文byte[]的长度(可能比加密前的明文长),新建一个存放解密后明文的byte[] byte[] DecryptDataArray = new byte[EncryptedDataArray.Length]; // 把解密后的数据读入到DecryptDataArray csDecrypt.Read(DecryptDataArray, 0, DecryptDataArray.Length); msDecrypt.Close(); csDecrypt.Close(); return DecryptDataArray; }
有一点需要注意,DES加密是以数据块为单位加密的,8个字节一个数据块,如果待加密明byte[]的长度不是8字节的整数倍,算法先用值为“0”的byte补足8个字节,然后进行加密。所以加密后的密文长度一定是8的整数倍。这样的密文解密后如果补了0值的byte,则解密后这些0值的byte依然存在。比如上例中要加密的明文是:
“Here is some data to encrypt. 这里是一些要加密的数据。”
转成明文byte[]后是66个字节,DES算法就会补上6个0值的byte,补到72个字节。这样加密后再解密回来的密文byte[]解码后的字符串就是这样的:
"Here is some data to encrypt. 这里是一些要加密的数据。\0\0\0\0\0\0"
5、 从编码字节流转成字符串明文
// 使用前面定义的Encoding,utf-8的编码把byte[]转成字符串
plainTextString = sEncoding.GetString(finalPlainTextArray);
六、非对称加密之RSA加密和解密的讲解