VB.NET加密字符串在解密时与原始字符串不同,缺少某些文本

时间:2015-10-20 18:36:41

标签: vb.net encryption cryptography

我正在做一些服务器/客户端编码,我需要加密数据。

我有以下用于加密和解密的类 - 在网上找到了一些代码并将其更改以供我使用。

Secure.vb

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

Public Class Secure
#Region "Encryption Salt"
Private strSalt = "MyTest"
#End Region

#Region "Enum"
Public Enum CryptoAction
    Encrypt = 1
    Decrypt = 2
End Enum
#End Region

Public Sub New()

End Sub

Private Function CreateKey() As Byte()
    Dim strpassword As String = strSalt

    Dim chrData() As Char = strpassword.ToCharArray
    Dim intLength As Integer = chrData.GetUpperBound(0)
    Dim bytDataToHash(intLength) As Byte

    For i As Integer = 0 To chrData.GetUpperBound(0)
        bytDataToHash(i) = CByte(Asc(chrData(i)))
    Next

    Dim SHA512 As New System.Security.Cryptography.SHA512Managed
    Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)
    Dim bytKey(31) As Byte

    For i As Integer = 0 To 31
        bytKey(i) = bytResult(i)
    Next

    Return bytKey
End Function

Private Function CreateIV() As Byte()
    Dim strPassword As String = strSalt

    Dim chrData() As Char = strPassword.ToCharArray
    Dim intLength As Integer = chrData.GetUpperBound(0)
    Dim bytDataToHash(intLength) As Byte

    For i As Integer = 0 To chrData.GetUpperBound(0)
        bytDataToHash(i) = CByte(Asc(chrData(i)))
    Next

    Dim SHA512 As New System.Security.Cryptography.SHA512Managed
    Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)
    Dim bytIV(15) As Byte

    For i As Integer = 32 To 47
        bytIV(i - 32) = bytResult(i)
    Next

    Return bytIV 'Return the IV.
End Function

Public Function Process(ByVal encString As String, ByVal Direction As CryptoAction, Optional ByVal Encrypted As Boolean = False) As String
    Try
        Dim encBytes() As Byte = Nothing
        If Direction = CryptoAction.Decrypt Then
            encBytes = Convert.FromBase64String(encString)
        Else
            encBytes = New System.Text.UnicodeEncoding().GetBytes(encString)
        End If

        Dim bytBuffer(4096) As Byte
        Dim lngBytesProcessed As Long = 0
        Dim lngStringLength As Long = encBytes.Length
        Dim intBytesInCurrentBlock As Integer = 0
        Dim csCryptoStream As CryptoStream = Nothing
        Dim cspRijndael As New System.Security.Cryptography.RijndaelManaged
        Dim strOutput As String = Nothing
        Dim bytKey() As Byte = CreateKey()
        Dim bytIV() As Byte = CreateIV()
        Dim iStream As New MemoryStream(encBytes)
        Dim oStream As New MemoryStream

        cspRijndael.Padding = PaddingMode.Zeros

        Select Case Direction
            Case CryptoAction.Encrypt
                csCryptoStream = New CryptoStream(oStream, _
                                                  cspRijndael.CreateEncryptor(bytKey, bytIV), _
                                                  CryptoStreamMode.Write)

            Case CryptoAction.Decrypt
                csCryptoStream = New CryptoStream(oStream, _
                cspRijndael.CreateDecryptor(bytKey, bytIV), _
                CryptoStreamMode.Write)
        End Select

        While lngBytesProcessed < lngStringLength
            intBytesInCurrentBlock = iStream.Read(bytBuffer, 0, 4096)
            csCryptoStream.Write(bytBuffer, 0, intBytesInCurrentBlock)
            lngBytesProcessed = lngBytesProcessed + _
                                    CLng(intBytesInCurrentBlock)
        End While

        If Direction = CryptoAction.Decrypt Then
            strOutput = System.Text.Encoding.Unicode.GetString(oStream.ToArray)
        Else
            strOutput = Convert.ToBase64String(oStream.ToArray)
        End If

        csCryptoStream.Close()
        iStream.Close()
        oStream.Close()

        Return strOutput
    Catch ex As Exception
        Return ex.Message
    End Try
End Function
End Class

然后执行以下操作:

Sub Main()

    Dim TestString As String = "<DebugResponse text=""Received Test""/>"

    Console.WriteLine("Original string: " & vbCrLf & TestString & vbCrLf)

    Dim Encrypter As New Secure

    Dim encrypted As String = Encrypter.Process(TestString, Secure.CryptoAction.Encrypt)

    Console.WriteLine("Encrypted string: " & vbCrLf & encrypted & vbCrLf)

    Dim decrypted As String = Encrypter.Process(encrypted, Secure.CryptoAction.Decrypt)

    Console.WriteLine("Decrypted string: " & vbCrLf & decrypted)

    Console.ReadLine()

End Sub

解密后的字符串的结果将返回

<DebugResponse text="Received Te

为什么呢? 我看不出错误在哪里:(

1 个答案:

答案 0 :(得分:0)

问题是我在评论中怀疑流没有正确刷新。完成写作后,您需要致电[FlushFinalBlock][1]

文档对此的原因不是很清楚,但我想这是因为加密工作在16字节块上,显然它不能加密块直到它拥有所有数据。虽然它有一个部分块(就像你在写完之后的情况一样),你需要调用FlushFinalBlock告诉它该部分块实际上是完整的数据。

因此总结一下,将csCryptoStream.FlushFinalBlock放在写入流的while循环之后。

相关问题