第二部分 密钥加密
In the Part 1 we learnt the basics of Cryptography and related .NET Framework classes. In this article we are going to see how to work with Secret Key Encryption using Triple-DES algorithm.
在命名空间System.Security.Cryptography 中包含了一个叫TripleDESCryptoServiceProvider的类提供了3-DES加密数据的方法.DES的含义是数据加密标准这三个英文单词的首字母,单词Triple的使用实际是说这种加密方式将原始数据加密了3次.
密钥加密有俩个必备条件:
- A secret key 密钥
- An initialization vector 初始化向量
这种加密算法使用了一种"链"的技术加密数据.使用这种技术时,一个完整的数据是被分成了若干小块分别进行加密的.前一个加密过的块又被用来加密当前的块,如此反复到最后一块,就像一条链一样,一环一环相扣!
初始化向量是作为一个加密和解密第一个块字节的种子使用的.这将会保证两个数据块不会产生相同的加密块的文本.
在使用TripleDESCryptoServiceProvider类加密时要注意:密钥必须是24字节的bytes数据类型,初始化向量必须是8字节的bytes型.
Example of using TripleDESCryptoServiceProvider class
在这个例子中我们首行创建一个叫做SecurityHelper的类,这个类将为我们加密和解密字符串数据.下面是这个类的代码:
Imports System.Security.Cryptography Imports System.IO Imports System.Text
Public Class SecurityHelper Public Key() As Byte Public IV() As Byte
Public Function Encrypt(ByVal strData As String) As Byte() Dim data() As Byte = ASCIIEncoding.ASCII.GetBytes(strData) Dim tdes As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider If Key Is Nothing Then tdes.GenerateKey() tdes.GenerateIV() Key = tdes.Key IV = tdes.IV Else tdes.Key = Key tdes.IV = IV End If Dim encryptor As ICryptoTransform = tdes.CreateEncryptor() Dim ms As New MemoryStream Dim cs As CryptoStream = New CryptoStream(ms, encryptor, CryptoStreamMode.Write) cs.Write(data, 0, data.Length) cs.FlushFinalBlock() ms.Position = 0 Dim result(ms.Length - 1) As Byte ms.Read(result, 0, ms.Length) cs.Close() Return result End Function
Public Function Decrypt(ByVal data() As Byte) As String Dim tdes As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider tdes.Key = Key tdes.IV = IV Dim decryptor As ICryptoTransform = tdes.CreateDecryptor() Dim ms As New MemoryStream Dim cs As CryptoStream = New CryptoStream(ms, decryptor, CryptoStreamMode.Write) cs.Write(data, 0, data.Length) cs.FlushFinalBlock() ms.Position = 0 Dim result(ms.Length - 1) As Byte ms.Read(result, 0, ms.Length) cs.Close() Return ASCIIEncoding.ASCII.GetString(result) End Function
End Class
Let's examine the code step by step:
现在我们来一步一步的解释这段代码
- We create a class called SecurityHelper with two functions Encrypt() and Decrypt(). The former accepts the string to be encrypted and returns encrypted form of the string as a byte array. The later accepts the encrypted data in the form of a byte array and returns decrypted data as a string.
首先我们创建了一个叫做SecurityHelper的类,它有两个方法,一个是加密,一个是解密.加密方法接收要被加密的字符串并将加密过的数据作为一个字节数组返回.解密方法则正好相反,他是接收被加密数据的字节数组,返回的是解密过的字符串.
- The class has two public variables of byte array type. They are used to assign the secret key and initialization vector.
这个类有两个公共的字节数组变量.他们分别被赋值给了密钥和初始化向量.
- In the Encrypt() function we first convert the string to be encrypted into a byte array using GetBytes() method.
在加密方法中我们首先把要被加密的字符串转换成字节数组类型.我们使用的是GetBytes()方法做转换的
- We then create an instance of TripleDESCryptoServiceProvider class
然后我们创建TripleDESCryptoServiceProvider类的实例.
- The key and initialization vector can be supplied externally by you or TripleDESCryptoServiceProvider class can generate one automatically for you. If user has not supplied key and IV we call GenerateKey() and GenerateIV() methods respectively. These methods create a random key and IV automatically for you. We assign the generated key and IV to public variables Key and IV.
密钥和初始化向量可以由你自己从外部提供,也可以由TripleDESCryptoServiceProvider 类自动为你生成.如果用户没用提供密钥和初始化向量,我们就分别调用GenerateKey() 和GenerateIV() 方法自动生成.这两个方法将为你随机生成密钥和初始化向量.然后我们再把它们分别赋值给公共变量Key 和 IV.
- Then we call CreateEncryptor() method of TripleDESCryptoServiceProvider class and collect its return value in a variable of type ICryptoTransform. The ICryptoTransform interface defines the basic operations of cryptographic transformations.
然后我们调用 TripleDESCryptoServiceProvider类的 CreateEncryptor() 方法,并以ICryptoTransform作为返回值类型得到.ICryptoTransform 接口定义了加密转换的一些基本操作.
- We then create a memory stream. The encrypted data will be put inside this stream.
然后我们创建一个内存流.把被加密的数据放入这个流中.
- We also create a CryptoStream and pass the memory stream and the encryptor created above.
我们也创建一个CryptoStream 流,并连同上一步创建的流一起传递.
- Next, we write the data to be encrypted to the CryptoStream object. The CryptoStream object stores the encrypted version of the data in the supplied memory stream.
接着,我们把加密过的数据写入CryptoStream对象.CryptoStream对象存放着内存流中加密数据的加密版本.
- Finally, we read the memory stream for encrypted data. Put that data in an array of bytes and return it to the caller.
最后,我们从内存流中读取加密数据,并把这些数据放入一个字节数组中返回给他的调用者.
Decryption process is similar but follows reverse path. The only major difference between encryption and decryption code is that in case of decryption we call CreateDecryptor() method of TripleDESCryptoServiceProvider class.
解密过程是类似的,只是把这个过程反过来.在加密和解密代码中的主要不同是:在解密过程中我们使用TripleDESCryptoServiceProvider 类的CreateDecryptor() 方法.