我正在做一些服务器/客户端编码,我需要加密数据。
我有以下用于加密和解密的类 - 在网上找到了一些代码并将其更改以供我使用。
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
为什么呢? 我看不出错误在哪里:(
答案 0 :(得分:0)
问题是我在评论中怀疑流没有正确刷新。完成写作后,您需要致电[FlushFinalBlock][1]
。
文档对此的原因不是很清楚,但我想这是因为加密工作在16字节块上,显然它不能加密块直到它拥有所有数据。虽然它有一个部分块(就像你在写完之后的情况一样),你需要调用FlushFinalBlock告诉它该部分块实际上是完整的数据。
因此总结一下,将csCryptoStream.FlushFinalBlock
放在写入流的while循环之后。