2017-04-15 13 views
0

Visual Basicで暗号化されたメッセージングプログラムを作成しているので、バックストーリーがありません。メッセージが送信されると、Base 64にエンコードされ(暗号化されてバイト配列に変換された後)、Base 64はUnicodeを使用した文字列として表示されます(データは実際には変更されません)メッセージの種類、文字列が他のコンピュータに送信されます(私はチェックし、送信されたデータは受信したデータと正確に一致しないので問題はありません)。 Base64/Unicode文字列が受信されると、通常のUnicode文字列に戻され(このデータは送信されたデータと完全に一致します)、データは復号化されます。これは問題が開始したとき、たいていの場合は動作しますが、特定の文字シーケンスを送信すると、受信側で別の表示をします(アジア文字の場合と同じように)。今いくつかの例のために:Visual BasicのUnicodeエンコーディングエラー:一部の文字が正しくエンコードされない

これは、暗号化された後のデータは、ベース64に変換され、パディングを加えた:

{/} C/1rcE9CwYDEnoaxNVT2Xme/pky6yDRGo3lcG12G/h8= {\} 

これはrecived、再エンコードされたデータである。

{/} C/1rcE9CwYDEnoaxNVT2Xme/pky6yDRGo3lcG12G/h8= {\} 

あなたはエラーがありません見ることができるように、これは暗号化されたデータ(文字列を暗号化する「EncryptionTest」)である:

Encrypt: EncryptionTest with 0K2V4Y0/aXrnGpcVP1d2JEGKAZDWZWuffXA1Iv0gFbc= got ﴋ火䉏胁黄놆吵延뽧䲦좺䘴禣᭜虝῾ 

これは、受信および復号化されたデータである。

Decrypt: ﴋ火䉏胁黄놆吵延뽧䲦좺䘴禣᭜虝῾ with 0K2V4Y0/aXrnGpcVP1d2JEGKAZDWZWuffXA1Iv0gFbc= got EncryptionTest 

それは私がこれは何が起こるかである文字列「ワンダフル」を送信ただし場合、完璧に働いた:

Encrypt: Wonderful with 0K2V4Y0/aXrnGpcVP1d2JEGKAZDWZWuffXA1Iv0gFbc= got 폮斚䢹뱊袗櫮㓟翔ǔ劇辑頭뷳ﭤ� 

Decrypt: 폮斚䢹뱊袗櫮㓟翔ǔ劇辑頭뷳ﭤ� with 0K2V4Y0/aXrnGpcVP1d2JEGKAZDWZWuffXA1Iv0gFbc= got Wonderf牏匢否喏幙‥ 

間違って何かが、私は削除する場合"Wondeful"の最後の "l":

Encrypt: Wonderfu with 0K2V4Y0/aXrnGpcVP1d2JEGKAZDWZWuffXA1Iv0gFbc= got 폮斚䢹뱊袗櫮㓟팾甎ᑁᗺ寑핕杷 
Decrypt: 폮斚䢹뱊袗櫮㓟팾甎ᑁᗺ寑핕杷 with 0K2V4Y0/aXrnGpcVP1d2JEGKAZDWZWuffXA1Iv0gFbc= got Wonderfu 

もう一度うまくいきます。エラーは、base64からのメッセージのデコードとそれを表示する間に発生しているので、解読機能が責任を負うことを意味する必要があります。ここで私の暗号化と解読機能が役に立ちます。

Function EncryptAESString(data As String, key As String) 
    Dim keybytes() As Byte = Convert.FromBase64String(key) 
    Dim ivbytes() = Convert.FromBase64String(HashString("TestIV2", "MDA5")) 
    Dim encrypted() As Byte 
    Using aesAlg As Aes = Aes.Create() 
     aesAlg.Padding = PaddingMode.Zeros 
     aesAlg.Key = keybytes 
     aesAlg.IV = ivbytes 
     Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV) 
     Using msEncrypt As New MemoryStream() 
      Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write) 
       Using swEncrypt As New StreamWriter(csEncrypt, uni) 
        swEncrypt.Write(data) 
       End Using 
       encrypted = msEncrypt.ToArray() 
      End Using 
     End Using 
    End Using 
    DebugPrint("Encrypt: " + data + " with " + key + " got " + uni.GetString(encrypted)) 
    Return uni.GetString(encrypted) 
End Function 

Function DecryptAESString(data As String, key As String) 
    Dim databyte() As Byte = uni.GetBytes(data) 
    Dim keybytes() As Byte = Convert.FromBase64String(key) 
    Dim ivbytes() = Convert.FromBase64String(HashString("TestIV2", "MDA5")) 
    Dim plaintext As String = Nothing 
    Using aesAlg As Aes = Aes.Create() 
     aesAlg.Padding = PaddingMode.Zeros 
     aesAlg.Key = keybytes 
     aesAlg.IV = ivbytes 
     Dim decryptor As ICryptoTransform = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV) 
     Using msDecrypt As New MemoryStream(databyte) 
      Using csDecrypt As New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read) 
       Using srDecrypt As New StreamReader(csDecrypt, uni) 
        plaintext = srDecrypt.ReadToEnd() 
       End Using 
      End Using 
     End Using 
    End Using 
    databyte = Nothing 
    keybytes = Nothing 
    ivbytes = Nothing 
    DebugPrint("Decrypt: " + data + " with " + key + " got " + plaintext) 
    Return plaintext 
End Function 
+0

任意のバイナリデータを表すためにUnicodeを使用しないでください。人間が消費するために印刷したい場合は、HexまたはBase64でエンコードして、何が起こっているのかを確認してください。 –

+0

uni.GetString()はバグです。* encrypted *はutf-16でエンコードされたテキストではありません。より早くbase64に変換する必要があります。 @ArtjomB。 –

+0

暗号化の後、データはbase64としてエンコードされます。 –

答えて

0

あなたは、最後のブロックが書き込まれるためにUsing csEncryptencrypted = msEncrypt.ToArray()外を移動する必要があります。これは、基本的には、パディングが適用され、平文の最後のブロックが書き込まれる前に、暗号文バイトを現在生成していることを意味します。

Using msEncrypt As New MemoryStream() 
    Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write) 
     Using swEncrypt As New StreamWriter(csEncrypt, uni) 
      swEncrypt.Write(data) 
     End Using 
    End Using 
    encrypted = msEncrypt.ToArray() 
End Using 

その他の問題は、文字列がバイナリデータのコンテナではないことです。いくつかのバイトが失われる可能性があります。文字列を印刷する場合は、HexまたはBase64のようなものを使用する必要があります。

暗号化中はReturn Convert.ToBase64String(encrypted)を使用し、復号化の際には逆の機能Dim databyte() As Byte = Convert.FromBase64String(data)を使用する必要があります。

+0

ありがとう、私はバイト配列が暗号化と解読を経る前後に一致するかどうかチェックするべきです。私は、データの一部がすべてのエンコードとデコード中に失われたと考えました。 –

+0

nvm、これは大部分のエンコード・スクラップを修正しますが、特定の文字列でもメッセージが間違って表示されることがあります –

+0

これらのメッセージはどのようなものですか?私は私の答えを少し拡張することに注意してください。 –

関連する問題