因此,我在Visual Basic中创建一个加密的消息传递程序,这是背景故事。当发送消息时,它被编码到Base 64中(在加密并变成字节数组之后),然后使用Unicode将Base 64表示为字符串(实际上没有任何数据被更改),添加了一些填充以区分消息类型,然后字符串被发送到另一台计算机(我检查过,发送的数据与收到的数据完全匹配,因此没有问题)。收到后,base64 / Unicode字符串将变回常规的Unicode字符串(此数据与发送的数据完全匹配,因此没有问题),然后数据被解密,这是问题开始时,它会成功解密并显示,它大部分时间都有效但有时如果你发送一个特定的字符序列,接收端会以不同的方式显示它(就像它们将是亚洲字符一样)。现在举一些例子:
这是加密后的数据,转换为base 64,并添加了填充:
{/} C/1rcE9CwYDEnoaxNVT2Xme/pky6yDRGo3lcG12G/h8= {\}
这是经过重新编码和重新编码的数据:
{/} C/1rcE9CwYDEnoaxNVT2Xme/pky6yDRGo3lcG12G/h8= {\}
正如您所看到的,没有错误,这是加密数据(加密字符串" EncryptionTest"):
Encrypt: EncryptionTest with 0K2V4Y0/aXrnGpcVP1d2JEGKAZDWZWuffXA1Iv0gFbc= got ﴋ火䉏胁黄놆吵延뽧䲦좺䘴禣᭜虝῾
这是收到和解密的数据:
Decrypt: ﴋ火䉏胁黄놆吵延뽧䲦좺䘴禣᭜虝῾ with 0K2V4Y0/aXrnGpcVP1d2JEGKAZDWZWuffXA1Iv0gFbc= got EncryptionTest
它工作得很好,但是如果我发送字符串" Wonderful"这就是:
Encrypt: Wonderful with 0K2V4Y0/aXrnGpcVP1d2JEGKAZDWZWuffXA1Iv0gFbc= got 폮斚䢹뱊袗櫮㓟翔ǔ劇辑頭뷳ﭤ�
Decrypt: 폮斚䢹뱊袗櫮㓟翔ǔ劇辑頭뷳ﭤ� with 0K2V4Y0/aXrnGpcVP1d2JEGKAZDWZWuffXA1Iv0gFbc= got Wonderf牏匢否喏幙‥
出了点问题,但如果我删除" l"在#34; Wondeful":
结束时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 :(得分:0)
您需要将encrypted = msEncrypt.ToArray()
移到Using csEncrypt
之外,以便写入最后一个块。这基本上意味着您在应用填充之前当前正在生成密文字节,并且写入了明文的最后一个块。
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)
。