逐步解說:在 Visual Basic 中加密和解密字串

本逐步解說示範如何使用類別, TripleDES 使用三重資料加密標準 (3DES) 演算法來加密和解密字串。 第一個步驟是建立簡單的包裝函式類別,以封裝 3DES 演算法,並將加密的數據儲存為base-64編碼字串。 然後,該包裝函式會用來安全地將私人用戶數據儲存在可公開存取的文本檔中。

您可以使用加密來保護用戶密碼(例如密碼),並讓未經授權的使用者無法讀取認證。 這可保護已授權使用者的身分識別免於遭竊,進而保護用戶的資產,並提供不可否認性。 加密也可以保護用戶的數據不受未經授權的使用者存取。

如需詳細資訊,請參閱 密碼編譯服務。

這很重要

Rijndael (現在稱為進階加密標準 [AES]) 和三重數據加密標準 (3DES) 演算法提供比 DES 更高的安全性,因為它們的計算密集程度更高。 如需詳細資訊,請參閱 DES 和 Rijndael。

建立加密包裝層

  1. 建立類別 Simple3Des 以封裝加密和解密方法。

    Public NotInheritable Class Simple3Des
    End Class
    
  2. 將密碼編譯命名空間的匯入新增至包含 Simple3Des 類別的檔案開頭。

    Imports System.Security.Cryptography
    
  3. 在類別 Simple3Des 中,新增私有欄位以儲存 3DES 密碼服務提供者、指定的金鑰,以及格式版本、鹽大小和迭代次數。

    Private TripleDes As TripleDES = TripleDES.Create()
    
    Private Const FormatVersion As Byte = 1
    Private Const SaltSize As Integer = 16
    Private Const Iterations As Integer = 600000
    Private ReadOnly Key As String
    
  4. 新增一個私有方法,從指定的鍵和鹽值建立位元組陣列。

    Private Function DeriveKey(ByVal salt() As Byte) As Byte()
        ' Derive a key from the specified key and the salt.
        Using kdf As New Rfc2898DeriveBytes(
            Key, salt, Iterations, HashAlgorithmName.SHA256)
    
            Return kdf.GetBytes(TripleDes.KeySize \ 8)
        End Using
    End Function
    
  5. 新增一個結構子來儲存指定的金鑰。

    參數 key 會控制 EncryptData 和 DecryptData 方法。

    Sub New(ByVal key As String)
        ' Store the key. The encryption key and IV are created per message.
        Me.Key = key
    End Sub
    
  6. 新增加密字串的公用方法。

    Public Function EncryptData( 
        ByVal plaintext As String) As String
    
        ' Create a new salt and initialization vector for this message.
        Dim salt(SaltSize - 1) As Byte
        Using rng As RandomNumberGenerator = RandomNumberGenerator.Create()
            rng.GetBytes(salt)
        End Using
    
        TripleDes.Key = DeriveKey(salt)
        TripleDes.GenerateIV()
    
        ' Convert the plaintext string to a byte array.
        Dim plaintextBytes() As Byte = 
            System.Text.Encoding.Unicode.GetBytes(plaintext)
    
        ' Create the stream.
        Dim ms As New System.IO.MemoryStream
        ' Write the format version, salt, and initialization vector in front of
        ' the cipher text. The version identifies the salt length and iteration count.
        ms.WriteByte(FormatVersion)
        ms.Write(salt, 0, salt.Length)
        ms.Write(TripleDes.IV, 0, TripleDes.IV.Length)
    
        ' Create the encoder to write to the stream.
        Dim encStream As New CryptoStream(ms, 
            TripleDes.CreateEncryptor(), 
            System.Security.Cryptography.CryptoStreamMode.Write)
    
        ' Use the crypto stream to write the byte array to the stream.
        encStream.Write(plaintextBytes, 0, plaintextBytes.Length)
        encStream.FlushFinalBlock()
    
        ' Convert the encrypted stream to a printable string.
        Return Convert.ToBase64String(ms.ToArray)
    End Function
    
  7. 新增解密字串的公用方法。

    Public Function DecryptData( 
        ByVal encryptedtext As String) As String
    
        ' Convert the encrypted text string to a byte array.
        Dim encryptedBytes() As Byte = Convert.FromBase64String(encryptedtext)
    
        ' Read the header that precedes the cipher text. Only one format
        ' version exists, so reject anything else.
        Dim ivSize As Integer = TripleDes.BlockSize \ 8
        Dim headerSize As Integer = 1 + SaltSize + ivSize
        If encryptedBytes.Length < headerSize OrElse
            encryptedBytes(0) <> FormatVersion Then
    
            Throw New CryptographicException(
                "The encrypted data is not in the expected format.")
        End If
    
        Dim salt(SaltSize - 1) As Byte
        Dim iv(ivSize - 1) As Byte
        Array.Copy(encryptedBytes, 1, salt, 0, SaltSize)
        Array.Copy(encryptedBytes, 1 + SaltSize, iv, 0, ivSize)
    
        TripleDes.Key = DeriveKey(salt)
        TripleDes.IV = iv
    
        ' Create the stream.
        Dim ms As New System.IO.MemoryStream
        ' Create the decoder to write to the stream.
        Dim decStream As New CryptoStream(ms, 
            TripleDes.CreateDecryptor(), 
            System.Security.Cryptography.CryptoStreamMode.Write)
    
        ' Use the crypto stream to write the byte array to the stream.
        decStream.Write(encryptedBytes, headerSize, 
            encryptedBytes.Length - headerSize)
        decStream.FlushFinalBlock()
    
        ' Convert the plaintext stream to a string.
        Return System.Text.Encoding.Unicode.GetString(ms.ToArray)
    End Function
    

    包裝函式類別現在可以用來保護用戶資產。 在此範例中,它會用來安全地將私人用戶數據儲存在可公開存取的文本檔中。

測試加密包裝函式

  1. 在不同的類別中,新增使用包裝函式 EncryptData 方法的方法來加密字串,並將它寫入使用者的 My Documents 資料夾。

    Sub TestEncoding()
        Dim plainText As String = InputBox("Enter the plain text:")
        Dim password As String = InputBox("Enter the password:")
    
        Dim wrapper As New Simple3Des(password)
        Dim cipherText As String = wrapper.EncryptData(plainText)
    
        MsgBox("The cipher text is: " & cipherText)
        My.Computer.FileSystem.WriteAllText( 
            My.Computer.FileSystem.SpecialDirectories.MyDocuments & 
            "\cipherText.txt", cipherText, False)
    End Sub
    
  2. 新增方法,以從使用者的 My Documents 資料夾讀取加密字串,並使用包裝函式 DecryptData 的方法解密字串。

    Sub TestDecoding()
        Dim cipherText As String = My.Computer.FileSystem.ReadAllText( 
            My.Computer.FileSystem.SpecialDirectories.MyDocuments & 
                "\cipherText.txt")
        Dim password As String = InputBox("Enter the password:")
        Dim wrapper As New Simple3Des(password)
    
        ' DecryptData throws if the wrong password is used.
        Try
            Dim plainText As String = wrapper.DecryptData(cipherText)
            MsgBox("The plain text is: " & plainText)
        Catch ex As System.Security.Cryptography.CryptographicException
            MsgBox("The data could not be decrypted with the password.")
        End Try
    End Sub
    
  3. 新增使用者介面程式代碼以呼叫 TestEncoding 和 TestDecoding 方法。

  4. 執行應用程式。

    當您測試應用程式時,請注意,如果您提供錯誤的密碼,它將不會解密數據。

另請參閱