|
■No78415 (魔界の仮面弁士) に追記
> (1) "Ryu" の 3 バイト (52, 79, 75)
> (2) "Password" の 8 バイト (50, 61, 73, 73, 77, 6F, 72, 64)
> (3) "20160112" の 8 バイト (32, 30, 31, 36, 30, 31, 31, 32)
> (4) CBC モード
最後は、VB.NET を使って、
> ただし No78397 の末尾に書いた 注2-C な実装のライブラリだった場合、
のパターンで実装した場合です。
結果は
> 32, 30, 31, 36, 30, 31, 31, 32, 82, 73, B0, 0C, 2F, A5, E2, 4B
> 『MjAxNjAxMTKCc7AML6XiSw==』
になるはず。
ついでに、標準の PaddingMode はあえて使わず、先の JavaScript 実装にあわせて、
0x05 で埋める実装にしてみました。元データが 3 バイトだと区別できないですけど。
Imports System
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Module Module1
Sub Main()
Dim cipherWithIV As String = EncryptWithIV("Ryu", "Password", "20160112")
Console.WriteLine(cipherWithIV)
Dim result2 As String = DecryptWithIV(cipherWithIV, "Password")
Console.WriteLine(result2)
Console.ReadLine()
End Sub
Function EncryptWithIV(ByVal plainText As String, ByVal key8 As String, ByVal iv As String) As String
Dim enc = Encoding.UTF8
Dim binKey8() As Byte = enc.GetBytes(key8)
Dim binIV8() As Byte = enc.GetBytes(iv)
Dim des As New DESCryptoServiceProvider() With {.Key = binKey8, .IV = binIV8}
des.Padding = PaddingMode.None '自分でパディングする
Dim result() As Byte
Using ms As New MemoryStream(), _
crypt As New CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write)
Dim binSrc() As Byte = enc.GetBytes(plainText)
'データ長が 8 の倍数バイトで無かった場合、パディングが必要です。
Dim paddingLength = (8 - (binSrc.Length Mod 8)) And 7
'パディング値としてここでは、固定値 0x05 を付与しています。
'(元が文字列なので、元データに 0x05 なバイナリが含まれることは無いと仮定)
Dim binSrcWithPadding = binSrc.Concat( _
Enumerable.Repeat(Of Byte)(5, paddingLength)).ToArray()
crypt.Write(binSrcWithPadding, 0, binSrcWithPadding.Length)
crypt.FlushFinalBlock()
'この実装では、先頭に IV を埋めて返しています
result = binIV8.Concat(ms.ToArray()).ToArray()
crypt.Close()
End Using
Dim base64Str As String = Convert.ToBase64String(result)
Return base64Str
End Function
Function DecryptWithIV(ByVal base64Str As String, ByVal key8 As String) As String
Dim enc = Encoding.UTF8
Dim cipherBinary() As Byte = Convert.FromBase64String(base64Str)
Dim binKey8() As Byte = enc.GetBytes(key8)
'先頭8バイトから IV を抜き出します
Dim binIV8() As Byte = cipherBinary.Take(8).ToArray()
'9バイト目以降の暗号文本体を取り出します
Dim binBody() As Byte = cipherBinary.Skip(8).ToArray()
Dim des As New DESCryptoServiceProvider() With {.Key = binKey8, .IV = binIV8}
des.Padding = PaddingMode.Zeros '自分でパディングを処理
Dim plainText As String
Using ms As New MemoryStream(binBody), _
crypt As New CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read), _
reader As New StreamReader(crypt, Encoding.UTF8)
crypt.Flush()
'末尾にパディングとして、0〜7 文字の 0x05 が
'付与されていることがあるので、これらを(手抜き実装で)除去します
plainText = reader.ReadToEnd().TrimEnd(ChrW(5))
reader.Close()
End Using
Return plainText
End Function
End Module
|