0

我在序列化对象时使用序列化加密时遇到问题。序列化加密错误

这是错误:

Failed to deserialize. Reason: End of Stream encountered before parsing was completed

这里是我的代码:

Imports System.IO 
Imports System.Security.Cryptography 
Imports System.Runtime.Serialization 
Imports System.Runtime.Serialization.Formatters.Binary 
Imports System.Text 

Module TestModEncryption 

Public Sub SaveEncryptedObjectToFile(FileName As String, Item As Object) 
    Dim fs As FileStream 
    Dim encryptor As CryptoStream 

    Dim formatter As New BinaryFormatter 

    Dim password As String = "MyPassword" 
    Dim salt As String = "InitialVector123" 

    Dim AES As AesManaged = New AesManaged 
    AES.Padding = PaddingMode.None 
    AES.Mode = CipherMode.CBC 

    Dim HashAlgorithm As String = "SHA1" 'Can be SHA1 or MD5 
    Dim PasswordIterations As Integer = 2 
    Dim InitialVector As String = "InitialVector123" 'This should be a string of 16 ASCII characters. 
    Dim KeySize As Integer = 256 'Can be 128, 192, or 256. 

    Dim InitialVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitialVector) 
    Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(salt) 
    Dim DerivedPassword As New Rfc2898DeriveBytes(password, SaltValueBytes, PasswordIterations) 
    Dim KeyBytes As Byte() = DerivedPassword.GetBytes(CInt(KeySize/8)) 

    Dim encryptTransf As ICryptoTransform = AES.CreateEncryptor(KeyBytes, InitialVectorBytes) 

    fs = New FileStream(FileName, FileMode.Create) 
    encryptor = New CryptoStream(fs, encryptTransf, CryptoStreamMode.Write) 

    Try 
     formatter.Serialize(encryptor, Item) 
    Catch e As SerializationException 
     Console.WriteLine("Failed to serialize. Reason: " & e.Message) 
     Throw 
    Finally 
     fs.Close() 
    End Try 
End Sub 

Public Function OpenEncryptedObjectFromFile(FileName As String) As Object 
    Dim fs As New FileStream(FileName, FileMode.Open) 
    Dim decryptor As CryptoStream 

    Dim ItemToReturn As New Object 

    Dim password As String = "MyPassword" 
    Dim salt As String = "InitialVector123" 

    Dim AES As AesManaged = New AesManaged 
    AES.Padding = PaddingMode.None 
    AES.Mode = CipherMode.CBC 

    Dim HashAlgorithm As String = "SHA1" 'Can be SHA1 or MD5 
    Dim PasswordIterations As Integer = 2 
    Dim InitialVector As String = "InitialVector123" 'This should be a string of 16 ASCII characters. 
    Dim KeySize As Integer = 256 'Can be 128, 192, or 256. 

    Dim InitialVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitialVector) 
    Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(salt) 
    Dim DerivedPassword As New Rfc2898DeriveBytes(password, SaltValueBytes, PasswordIterations) 
    Dim KeyBytes As Byte() = DerivedPassword.GetBytes(CInt(KeySize/8)) 

    Dim decryptTrans As ICryptoTransform = AES.CreateDecryptor(KeyBytes, InitialVectorBytes) 

    Try 
     Dim formatter As New BinaryFormatter 

     decryptor = New CryptoStream(fs, decryptTrans, CryptoStreamMode.Read) 
     ItemToReturn = DirectCast(formatter.Deserialize(decryptor), Object) 
     Return ItemToReturn 
    Catch e As SerializationException 
     MsgBox("Failed to deserialize. Reason: " & e.Message) 
     Return Nothing 
     'Throw 
    Finally 
     fs.Close() 
    End Try 
End Function 

End Module 
+0

'这应该是一个由16个ASCII字符组成的字符串?不可以。它应该是一个不可预知且唯一的字节串,最好来自一个安全的随机数生成器,并且每次调用函数时都应该有所不同。在PBKDF2中使用两次迭代完全是假的,事实上,在这种情况下完全使用PBKDF2是完全虚假的。 – ntoskrnl

回答

2

加密是有些复杂。首先得到加密工作,只是加密。从一段文字开始:“我像一个犰狳一样孤独地徘徊。”使用你的代码来加密和解密文本,忘记序列化。如果这个工作正常,那么只有在那时,使用你的工作加密代码来加密/解密序列化的对象。

你是否成功地序列化/反序列化你的对象没有任何加密?

匆匆一瞥,您需要将填充设置为PKCS#7(又名PKCS#5)。您的PaddingMode.None可能是导致此问题的原因。没有填充您的最终块可能无法正确处理。显然,你需要使用相同的填充进行加密和解密。