簡単な暗号化と復号化 (VB.NET版)

注意:
この文書は以前「.NETでいきまっしょい!」で公開していたものですが、公開以降メンテナンスされていません。 今や古い情報となった内容が記載されている場合があるのでご注意ください。

1.DES(Data Encryption Standard)による簡単な暗号化・復号化


 System.Security.Cryptography名前空間にあるDESCryptoServiceProviderというクラスを使うと、DES(Data Encryption Standard)と呼ばれるアルゴリズムで暗号化を行うことができます。 また、これを使えばDESで暗号化された文書を復号化(暗号の解読)することもできます。
 DESアルゴリズムは秘密鍵方式で、64ビット(8バイト)の鍵と初期化ベクタIVを指定する必要があります。 これらの値は、暗号化と復号化の際に同じ値を用いる必要があります。 異なる値を用いると、暗号化はできても復号化できないという事態になってしまいます。
 また、DESCryptoServiceProviderクラスののインスタンスにこれらの値を指定したあと、暗号化の際はCreateEncryptor()メソッド、復号化の際にはCreateDecryptor()メソッドの戻り値として得られるICryptoTransform型の対象暗号化オブジェクトと呼ばれるものを利用して実際に暗号化、復号化します。 さらに、この暗号化・復号化の処理にはCryptoStreamクラスのストリームを作成することで、入力のストリームを暗号化・復号化します。 これら一連の流れを記述したものが次のコードです。
 Text.txtが暗号化されるファイルで、UTF-8で記述されています。 これを暗号化し、Encrypted.txtというファイルに保存します。 さらに、このファイルを復号化したものをDecrypted.txtというファイルに保存します。 鍵には「password」という8文字、つまりちょうど8バイトのASCII文字を使用します。
ソースコード
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
Option Strict On

Imports System
Imports System.IO
Imports System.Text
Imports System.Security
Imports System.Security.Cryptography

Module Module1

    Sub Main()

        ' 鍵は64ビット(8バイト)である必要がある
        Dim key() As Byte = Encoding.ASCII.GetBytes("password")

        ' 暗号化して保存
        EncryptByDES("E:\Text.txt", "E:\Encrypted.txt", key)

        ' 復号化して保存
        DecryptByDES("E:\Encrypted.txt", "E:\Decrypted.txt", key)

    End Sub

    ' DES(Data Encryption Standard)によって暗号化する
    Sub EncryptByDES(ByVal inputFileName As String, ByVal encryptedFileName As String, ByVal encryptionKey() As Byte)

        Dim inputStream As FileStream
        Dim encryptedStream As FileStream

        ' 暗号化する対象のFileStreamオブジェクト
        inputStream = New FileStream(inputFileName, FileMode.Open, FileAccess.Read)

        ' 暗号化したものを書き込むためのFileStreamオブジェクト
        encryptedStream = New FileStream(encryptedFileName, FileMode.Create, FileAccess.Write)

        ' DESと呼ばれる方法で暗号化するためのオブジェクト
        Dim des As New DESCryptoServiceProvider()

        ' 鍵は64ビット(8バイト)のバイト配列である必要がある
        des.Key = encryptionKey

        ' 初期化ベクタ(暗号化と復号化の際には同じIVを必要とする)
        des.IV = encryptionKey

        ' CryptoStreamオブジェクトを作成する
        Dim transform As ICryptoTransform = des.CreateEncryptor() ' Encryptorを作成する
        Dim cryptoStream As New CryptoStream(encryptedStream, transform, CryptoStreamMode.Write)

        ' 暗号化する対象をバイト配列として読み込む
        Dim buffer() As Byte
        Dim length As Integer = CInt(inputStream.Length)

        ReDim buffer(length)

        inputStream.Read(buffer, 0, length)

        ' CryptoStreamによって暗号化して書き込む
        cryptoStream.Write(buffer, 0, length)

        ' CryptoStreamを閉じる
        cryptoStream.Close()

        ' FileStreamを閉じる
        inputStream.Close()
        encryptedStream.Close()

    End Sub


    ' DES(Data Encryption Standard)暗号を復号化する
    Sub DecryptByDES(ByVal inputFileName As String, ByVal decryptedFileName As String, ByVal decryptionKey() As Byte)

        Dim inputStream As FileStream
        Dim decryptedStream As StreamWriter

        ' 復号化する対象のFileStreamオブジェクト
        inputStream = New FileStream(inputFileName, FileMode.Open, FileAccess.Read)

        ' 復号化したものを書き込むためのStreamWriterオブジェクト
        decryptedStream = New StreamWriter(decryptedFileName, False, Encoding.UTF8)

        ' DESと呼ばれる方法で暗号化するためのオブジェクト
        Dim des As New DESCryptoServiceProvider()

        ' 鍵は64ビット(8バイト)のバイト配列である必要がある
        des.Key = decryptionKey

        ' 初期化ベクタ(暗号化と復号化の際には同じIVを必要とする)
        des.IV = decryptionKey

        ' CryptoStreamオブジェクトを作成する
        Dim transform As ICryptoTransform = des.CreateDecryptor() ' Decryptorを作成する
        Dim cryptoStream As New CryptoStream(inputStream, transform, CryptoStreamMode.Read)

        ' CryptoStreamから読み込むためのStreamReaderを作成する
        Dim reader As New StreamReader(cryptoStream)

        ' 復号化して書き込む
        decryptedStream.Write(reader.ReadToEnd())

        ' ストリームを閉じる
        reader.Close()
        cryptoStream.Close()

        decryptedStream.Close()

    End Sub

End Module
出力ファイル
E:\Text.txt
EF BB BF 54 68 69 73 20 69 73 20 61 20 73 61 6D
70 6C 65 20 6F 66 20 63 72 79 70 74 67 72 61 70
68 2E 0D 0A E3 81 93 E3 82 8C E3 81 AF E3 80 81
E6 9A 97 E5 8F B7 E5 8C 96 E3 83 BB E5 BE A9 E5
8F B7 E5 8C 96 E3 81 AE E3 82 B5 E3 83 B3 E3 83
97 E3 83 AB E3 81 A7 E3 81 99 E3 80 82

E:\Encrypted.txt
28 EB 99 8C D9 51 4A 32 C5 50 65 DE 08 7A 95 CE
CE 05 F3 52 A3 70 93 07 59 27 0E 80 B2 42 C0 16
1D E0 58 B3 3E 42 0B 9B 16 D2 DB 08 42 D5 D2 4E
3E 17 DC 40 F0 02 D4 2C 72 73 14 69 CF BB B0 AD
30 D4 EF 18 63 2D A8 A0 A3 BC 91 31 31 E0 EE 6E
43 81 F1 AE 69 C6 E1 1E C6 CE 3A 1D D6 53 95 F8

E:\Decrypted.txt
EF BB BF 54 68 69 73 20 69 73 20 61 20 73 61 6D
70 6C 65 20 6F 66 20 63 72 79 70 74 67 72 61 70
68 2E 0D 0A E3 81 93 E3 82 8C E3 81 AF E3 80 81
E6 9A 97 E5 8F B7 E5 8C 96 E3 83 BB E5 BE A9 E5
8F B7 E5 8C 96 E3 81 AE E3 82 B5 E3 83 B3 E3 83
97 E3 83 AB E3 81 A7 E3 81 99 E3 80 82
実行結果
実行結果
 16進数値の並びは、参考までに各ファイルをダンプしたものです。 当然のことですが、暗号化したファイルを同じ鍵で復号化すると、元のファイルと同じものが出力されます。

2.RC2アルゴリズムによる簡単な暗号化・復号化


 RC2アルゴリズムはDESアルゴリズムと同様に秘密鍵方式の暗号化アルゴリズムです。 RC2アルゴリズムを用いた場合では、DESによるものとは異なり、鍵には任意の長さのバイト配列を指定できます。 暗号化・復号化の方法など、それ以外の部分はほとんどDESの場合と同じです。
 次のコードはRC2アルゴリズムにより暗号化・復号化を行ったものです。 Text.txtの内容は先ほどと同じです。
ソースコード
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
Option Strict On

Imports System
Imports System.IO
Imports System.Text
Imports System.Security
Imports System.Security.Cryptography

Module Module1

    Sub Main()

        ' 鍵は任意のビット数で可
        Dim key() As Byte = Encoding.ASCII.GetBytes("longlongpassword")

        ' 初期化ベクタは8バイト
        Dim iv() As Byte = Encoding.ASCII.GetBytes("password")

        ' 暗号化して保存
        EncryptByRC2("E:\Text.txt", "E:\Encrypted.txt", key, iv)

        ' 復号化して保存
        DecryptByRC2("E:\Encrypted.txt", "E:\Decrypted.txt", key, iv)

    End Sub

    ' RC2アルゴリズムによって暗号化する
    Sub EncryptByRC2(ByVal inputFileName As String, ByVal encryptedFileName As String, ByVal encryptionKey() As Byte, ByVal iv() As Byte)

        Dim inputStream As FileStream
        Dim encryptedStream As FileStream

        ' 暗号化する対象のFileStreamオブジェクト
        inputStream = New FileStream(inputFileName, FileMode.Open, FileAccess.Read)

        ' 暗号化したものを書き込むためのFileStreamオブジェクト
        encryptedStream = New FileStream(encryptedFileName, FileMode.Create, FileAccess.Write)

        ' DESと呼ばれる方法で暗号化するためのオブジェクト
        Dim rc2 As New RC2CryptoServiceProvider()

        ' 鍵はビット数で可
        rc2.Key = encryptionKey

        ' 初期化ベクタ(暗号化と復号化の際には同じIVを必要とする)
        rc2.IV = iv

        ' CryptoStreamオブジェクトを作成する
        Dim transform As ICryptoTransform = rc2.CreateEncryptor() ' Encryptorを作成する
        Dim cryptoStream As New CryptoStream(encryptedStream, transform, CryptoStreamMode.Write)

        ' 暗号化する対象をバイト配列として読み込む
        Dim buffer() As Byte
        Dim length As Integer = CInt(inputStream.Length)

        ReDim buffer(length)

        inputStream.Read(buffer, 0, length)

        ' CryptoStreamによって暗号化して書き込む
        cryptoStream.Write(buffer, 0, length)

        ' CryptoStreamを閉じる
        cryptoStream.Close()

        ' FileStreamを閉じる
        inputStream.Close()
        encryptedStream.Close()

    End Sub


    ' RC2アルゴリズムで暗号化されたものを復号化する
    Sub DecryptByRC2(ByVal inputFileName As String, ByVal decryptedFileName As String, ByVal decryptionKey() As Byte, ByVal iv() As Byte)

        Dim inputStream As FileStream
        Dim decryptedStream As StreamWriter

        ' 復号化する対象のFileStreamオブジェクト
        inputStream = New FileStream(inputFileName, FileMode.Open, FileAccess.Read)

        ' 復号化したものを書き込むためのStreamWriterオブジェクト
        decryptedStream = New StreamWriter(decryptedFileName, False, Encoding.UTF8)

        ' DESと呼ばれる方法で暗号化するためのオブジェクト
        Dim rc2 As New RC2CryptoServiceProvider()

        ' 鍵はビット数で可
        rc2.Key = decryptionKey

        ' 初期化ベクタ(暗号化と復号化の際には同じIVを必要とする)
        rc2.IV = iv

        ' CryptoStreamオブジェクトを作成する
        Dim transform As ICryptoTransform = rc2.CreateDecryptor() ' Decryptorを作成する
        Dim cryptoStream As New CryptoStream(inputStream, transform, CryptoStreamMode.Read)

        ' CryptoStreamから読み込むためのStreamReaderを作成する
        Dim reader As New StreamReader(cryptoStream)

        ' 復号化して書き込む
        decryptedStream.Write(reader.ReadToEnd())

        ' ストリームを閉じる
        reader.Close()
        cryptoStream.Close()

        decryptedStream.Close()

    End Sub

End Module
出力ファイル
E:\Text.txt
EF BB BF 54 68 69 73 20 69 73 20 61 20 73 61 6D
70 6C 65 20 6F 66 20 63 72 79 70 74 67 72 61 70
68 2E 0D 0A E3 81 93 E3 82 8C E3 81 AF E3 80 81
E6 9A 97 E5 8F B7 E5 8C 96 E3 83 BB E5 BE A9 E5
8F B7 E5 8C 96 E3 81 AE E3 82 B5 E3 83 B3 E3 83
97 E3 83 AB E3 81 A7 E3 81 99 E3 80 82

E:\Encrypted.txt
09 42 65 E9 91 97 B5 79 B9 95 12 26 D3 E3 96 49
B1 C6 E7 F1 AA 75 D6 EA B9 6A BC D0 77 19 7C 0A
55 C8 80 24 9D 96 3C A8 A7 28 A8 1B 40 CE C4 54
34 CE 7C 47 57 B2 9C 8C 49 3E 46 0E F8 F5 5A 7C
26 87 97 FC 51 55 BF 2B 7F 32 14 38 74 00 EE 22
B6 BC 7C 73 C7 73 4C 2C 40 C7 DB D7 19 59 4A 77

E:\Decrypted.txt
EF BB BF 54 68 69 73 20 69 73 20 61 20 73 61 6D
70 6C 65 20 6F 66 20 63 72 79 70 74 67 72 61 70
68 2E 0D 0A E3 81 93 E3 82 8C E3 81 AF E3 80 81
E6 9A 97 E5 8F B7 E5 8C 96 E3 83 BB E5 BE A9 E5
8F B7 E5 8C 96 E3 81 AE E3 82 B5 E3 83 B3 E3 83
97 E3 83 AB E3 81 A7 E3 81 99 E3 80 82
実行結果
実行結果