チュートリアル: Visual Basic での文字列の暗号化と復号化

このチュートリアルでは、 TripleDES クラスを使用して、Triple Data Encryption Standard (3DES) アルゴリズムを使用して文字列を暗号化および復号化する方法について説明します。 最初の手順では、3DES アルゴリズムをカプセル化し、暗号化されたデータを base-64 でエンコードされた文字列として格納する単純なラッパー クラスを作成します。 その後、そのラッパーを使用して、パブリックにアクセスできるテキスト ファイルにプライベート ユーザー データを安全に格納します。

暗号化を使用すると、ユーザー シークレット (パスワードなど) を保護したり、承認されていないユーザーが資格情報を読み取れないようにしたりできます。 これにより、承認されたユーザーの ID が盗まれるのを防ぎ、ユーザーの資産を保護し、否認を防ぎます。 暗号化により、承認されていないユーザーがユーザーのデータにアクセスできないように保護することもできます。

詳細については、「暗号サービス」をご覧ください。

Von Bedeutung

Rijndael (現在は Advanced Encryption Standard [AES] と呼ばれる) アルゴリズムと Triple Data Encryption Standard (3DES) アルゴリズムは、計算負荷が高いため、DES よりも高いセキュリティを提供します。 詳細については、「DES と Rijndael」を参照してください。

暗号化ラッパーを作成するには

  1. 暗号化と復号化のメソッドをカプセル化する Simple3Des クラスを作成します。

    Public NotInheritable Class Simple3Des
    End Class
    
  2. 暗号化名前空間のインポートを、 Simple3Des クラスを含むファイルの先頭に追加します。

    Imports System.Security.Cryptography
    
  3. Simple3Des クラスで、プライベート フィールドを追加して、3DES 暗号化サービス プロバイダー、指定されたキー、および形式のバージョン、salt サイズ、および反復回数を格納します。

    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. 指定したキーと salt からバイト配列を作成するプライベート メソッドを追加します。

    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 メソッドを使用して文字列を暗号化し、ユーザーの [マイ ドキュメント] フォルダーに書き込むメソッドを追加します。

    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. アプリケーションを実行します。

    アプリケーションをテストするときに、間違ったパスワードを指定してもデータの暗号化が解除されないことに注意してください。

こちらも参照ください