NonSoft

DES暗号化のサンプル(VB.NET)

 サンプルソース
<このサンプルの概要>
DESとはData Encryption Standard(データ暗号化標準)の略で共通鍵暗号を採用した暗号化
アルゴリズムです。64ビットブロック毎に暗号します。鍵の長さも64ビットですが8ビット
毎に1ビットのパリティがつくため、実質的には56ビットになります。

DESは多くのコンピュータを使用すれば比較的簡単に解読できるので、DESの代わりに
トリプルDESが使用されるようになっています。トリプルDESとは単純にDESを3回繰り返す
事で、2つか3つの鍵を使用して暗号→復号→暗号の順で暗号化します。

DESが比較的簡単に解読出来るとは言っても、その道の博士のような人たちがお金と時間を
使って可能になる事で、一般人にとっては全然問題ない暗号化方式だと思います。
どんな暗号化方式も解読される可能性があると認識して使用する事が大事だと思います。
例えば、パスワードを時々変更するとか。。。

DES暗号化アルゴリズムは公開されているので、そのアルゴリズムをVB6で実現すると、
このサンプルのようになります。このサンプルの「DESアルゴリズムの初期化処理」では
PC1、PC2、LS、IP、MP、FP、EP、SBOXの値は途中省略していますのでご了承ください。

VB6版はこちらです。
DES暗号化のサンプル(VB6)

このサンプルをライブラリ(dll)化したものをご試用頂けます。
CryptMin暗号化ライブラリ(VB6版)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim datStr As String
    Dim keyStr As String
    Dim encStr As String
    Dim decStr As String
    Dim datBytes() As Byte
    Dim keyBytes() As Byte
    Dim encBytes() As Byte
    Dim decBytes() As Byte
    datStr = "1111111100000000101010100101010100000000111111110101010110101010"
    keyStr = "1000000101000001001000010001000100001001000001010000001111111111"
    datBytes = System.Text.Encoding.GetEncoding("SHIFT-JIS").GetBytes(datStr)
    keyBytes = System.Text.Encoding.GetEncoding("SHIFT-JIS").GetBytes(keyStr)
    InitCryptDes()
    Debug.Print("開始:" & Now)
    Debug.Print("暗号化前:" & datStr)
    encBytes = CryptDesBit(datBytes, True, keyBytes)
    encStr = System.Text.Encoding.GetEncoding("SHIFT-JIS").GetString(encBytes)
    Debug.Print("暗号化後:" & encStr)
    decBytes = CryptDesBit(encBytes, False, keyBytes)
    decStr = System.Text.Encoding.GetEncoding("SHIFT-JIS").GetString(decBytes)
    Debug.Print("復号化後:" & decStr)
    Debug.Print("終了:" & Now)
End Sub
実行結果例
開始:2009/07/02 18:08:26
暗号化前:1111111100000000101010100101010100000000111111110101010110101010
暗号化後:1011111001001010110111110010100101101001010011011101111010101101
復号化後:1111111100000000101010100101010100000000111111110101010110101010
終了:2009/07/02 18:08:27

Private PC1
Private PC2
Private LS
Private IP
Private MP
Private FP
Private EP
Private SBOX(7)

' 関数名    : CryptDesBit
' 返り値    : 暗号化/複合化した64ビット配列(64個の配列)
'           : エラー時は配列数-1で返す
' 引き数    : data(i) : 暗号化/複合化前のデータ64ビット配列(64個の配列)
'           : crypt(i): 暗号化(TRUE)または復号化(FALSE)
'           : key(i)  : 暗号化キー64ビット配列(64個の配列)
' 機能説明  : DESアルゴリズムで暗号化または複合化する
Private Function CryptDesBit(ByRef data() As Byte, ByVal crypt As Boolean, _
                             ByRef key() As Byte) As Byte()
    ReDim CryptDesBit(-1)
    Dim i As Long
    Dim j As Long
    Dim k As Long
    Dim t As Long
    Dim block(63) As Byte
    Dim dataLplusR(63) As Byte
    Dim keyPC1(55) As Byte
    Dim keyPC2(15, 47) As Byte
    Dim preSbox(47) As Byte
    Dim keyC(27) As Byte
    Dim keyD(27) As Byte
    Dim keyCD(55) As Byte
    Dim dataL(31) As Byte
    Dim dataR(31) As Byte
    Dim dataRback(31) As Byte
    Dim sboxBit(47) As Byte
    If UBound(key) <> 63 Or _
       UBound(data) <> 63 Then
        Exit Function
    End If
    For i = 0 To 63
        block(i) = key(i)
    Next i
    For i = 0 To 55
        keyPC1(i) = block(PC1(i) - 1)
    Next i
    For i = 0 To 27
        keyC(i) = keyPC1(i)
        keyD(i) = keyPC1(i + 28)
    Next i
    For i = 0 To 15
        For k = 0 To LS(i) - 1
            t = keyC(0)
            For j = 0 To 28 - 2
                keyC(j) = keyC(j + 1)
            Next j
            keyC(27) = t

            t = keyD(0)
            For j = 0 To 28 - 2
                keyD(j) = keyD(j + 1)
            Next j
            keyD(27) = t
        Next k
        For j = 0 To 27
            keyCD(j) = keyC(j)
            keyCD(j + 28) = keyD(j)
        Next j
        For j = 0 To 47
            keyPC2(i, j) = keyCD(PC2(j) - 1)
        Next j
    Next i
    For i = 0 To 63
        block(i) = data(i)
    Next i
    For i = 0 To 31
        dataL(i) = block(IP(i) - 1)
    Next i
    For i = 32 To 63
        dataR(i - 32) = block(IP(i) - 1)
    Next i
    For i = 0 To 15
        For j = 0 To 31
            dataRback(j) = dataR(j)
        Next j
        For j = 0 To 47
            If crypt Then
                preSbox(j) = dataR(EP(j) - 1) Xor keyPC2(i, j)
            Else
                preSbox(j) = dataR(EP(j) - 1) Xor keyPC2(15 - i, j)
            End If
        Next j
        For j = 0 To 7
            t = 6 * j
            k = SBOX(j)( _
                (((preSbox(t + 0) * 2) + (preSbox(t + 5) * 1)) * 16) + _
                ((preSbox(t + 1) * 8) + (preSbox(t + 2) * 4) + _
                 (preSbox(t + 3) * 2) + (preSbox(t + 4) * 1)))
            t = 4 * j
            sboxBit(t + 0) = (k \ 8) And 1
            sboxBit(t + 1) = (k \ 4) And 1
            sboxBit(t + 2) = (k \ 2) And 1
            sboxBit(t + 3) = (k \ 1) And 1
        Next j
        For j = 0 To 31
            dataR(j) = sboxBit(MP(j) - 1) Xor dataL(j)
        Next j
        For j = 0 To 31
            dataL(j) = dataRback(j)
        Next j
    Next i
    For i = 0 To 31
        t = dataL(i)
        dataL(i) = dataR(i)
        dataR(i) = t
    Next i
    For i = 0 To 31
        dataLplusR(i) = dataL(i)
    Next i
    For i = 32 To 63
        dataLplusR(i) = dataR(i - 32)
    Next i
    For i = 0 To 63
        block(i) = dataLplusR(FP(i) - 1)
    Next i
    CryptDesBit = block
    Exit Function
End Function

' 関数名    : InitCryptDes
' 返り値    : 無し
' 引き数    : 無し
' 機能説明  : DESアルゴリズムの初期化処理を行なう
Private Sub InitCryptDes()
    PC1 = New Integer() { 57, 49, 41, 33, 25, 17, 9, ...}
    PC2 = New Integer() { 14, 17, 11, 24, 1, 5, ...}
    LS = New Integer() {1, 1, 2, 2, ...}
    IP = New Integer() { 58, 50, 42, 34, 26, 18, 10, 2, ...}
    MP = New Integer() { 16, 7, 20, 21, 29, 12, 28, 17, ...}
    FP = New Integer() { 40, 8, 48, 16, 56, 24, 64, 32, ...}
    EP = New Integer() { 32, 1, 2, 3, 4, 5, ...}
    SBOX(0) = New Integer() { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, ...}
    SBOX(1) = New Integer() { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, ...}
    SBOX(2) = New Integer() { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, ...}
    SBOX(3) = New Integer() { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, ...}
    SBOX(4) = New Integer() { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, ...}
    SBOX(5) = New Integer() { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, ...}
    SBOX(6) = New Integer() { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, ...}
    SBOX(7) = New Integer() { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, ...}
    Exit Sub
End Sub