好的,所以我正在尝试创建一个系统,我将字典序列化,然后对其进行加密,然后对其进行解密,然后恢复字典。
它还包括一些基于设置的选择语句,用户可以设置是否始终,从不或提示加密。
我一直在尝试跟随CryptoStream类文档,但由于某些原因,这不起作用。我认为加密可能有效,但文件比没有加密的.ser等级要小得多,所以我不知道。解密生成"尝试反序列化空流。"错误,这是非常自我解释,但我无法解决如何解决它。
备份和恢复无需加密即可正常工作。
以下是相关的子程序(以及GIT链接,如果它更容易),任何帮助将非常感谢!这是一个A Level计算项目,所以我不太关心加密的实际强度(真的不想开始使用散列和盐析),只是它有效。
加密备份:
Private Sub encryptBackup()
Dim key As Byte()
Dim IV As Byte() = New Byte() {}
Using MD5 As New MD5CryptoServiceProvider
Dim tmp = System.Text.Encoding.UTF8.GetBytes(InputBox("Please insert password:", "Password Input") & "This is most definitely not an obtuse amount of salt")
key = MD5.ComputeHash(tmp)
IV = MD5.ComputeHash(key)
End Using
Using cryptoRijndael = Rijndael.Create()
Dim cryptoCryptor As ICryptoTransform = cryptoRijndael.CreateEncryptor(key, IV)
Using fStream As New FileStream(fldBackupJobs & "\Backup Files\" & Strings.Replace(Strings.Replace(Now, ":", "_"), "/", ".") & ".bin", FileMode.OpenOrCreate), cStream As New CryptoStream(fStream, cryptoCryptor, CryptoStreamMode.Write)
Dim Formatter As New BinaryFormatter
Formatter.Serialize(cStream, photoJobs)
MsgBox("Written to file")
End Using
End Using
End Sub
解密备份:
Private Sub decryptBackup(pathsStr As String)
photoJobs = Nothing
Dim key As Byte()
Dim IV As Byte() = New Byte() {}
Using MD5 As New MD5CryptoServiceProvider
Dim tmp = System.Text.Encoding.UTF8.GetBytes(InputBox("Please insert password:", "Password Input") & "This is most definitely not an obtuse amount of salt")
key = MD5.ComputeHash(tmp)
IV = MD5.ComputeHash(key)
End Using
Using cryptoRijndael = Rijndael.Create()
Dim cryptoCryptor As ICryptoTransform = cryptoRijndael.CreateEncryptor(key, IV)
pathstr = OpenFileDialog.FileName
Using fStream As New FileStream(pathstr, FileMode.Open), cStream As New CryptoStream(fStream, cryptoCryptor, CryptoStreamMode.Read)
Dim Formatter As New BinaryFormatter
photoJobs = CType(Formatter.Deserialize(cStream), Dictionary(Of String, PhotoJob))
MsgBox("Backup Restored")
End Using
End Using
End Sub
GIT链接:https://github.com/hughesjs/Photo-Gift-Manager
提前致谢!!
答案 0 :(得分:1)
代码的第一部分让我暂停,因为(超出GoTo
)看起来密码方法依赖于文件扩展名。由于用户可以通过资源管理器进行更改,因此非常脆弱。并且不要让用户选择:如果需要加密,那就去做;如果没有,不要。当然,加密方法不应该由他们决定(我们为他们做出决定会花大价钱)。
使用我恰好有用的BindingList(of Animal)
进行加密:
Dim key As Byte()
Dim iv As Byte() = New Byte() {}
' see notes below
Using MD5 As New MD5CryptoServiceProvider
' UTF8 not unicode; convert password to Byte()
Dim tmp = Encoding.UTF8.GetBytes(password & "$*^!#" & password)
' hash the PW to get the crypto Key
key = MD5.ComputeHash(tmp)
' hash the Key to get the IV
iv = MD5.ComputeHash(key)
End Using
Using rijAlg = Rijndael.Create()
' Create cryptor using the Key and IV
Dim cryptor As ICryptoTransform = rijAlg.CreateEncryptor(key, IV)
' Open a filestream for the output file, wrap it with
' a CryptoStream created with the cryptor in WRITE (output) mode
Using fs As New FileStream("C:\Temp\crypto.bin", FileMode.OpenOrCreate),
cs As New CryptoStream(fs, cryptor, CryptoStreamMode.Write)
' serialize collection to CryptoStream (to disk)
Dim bf As New BinaryFormatter
bf.Serialize(cs, mcol)
End Using
End Using
要解密,请使用相同的密钥和IV:
mcol = Nothing
' the comments above pertain, just in reverse
Using rijAlg = Rijndael.Create()
Dim cryptor As ICryptoTransform = rijAlg.CreateDecryptor(key, iv)
Using fs As New FileStream("C:\Temp\crypto.bin", FileMode.Open),
cs As New CryptoStream(fs, cryptor, CryptoStreamMode.Read)
Dim bf As New BinaryFormatter
' Convert object to type
mcol = CType(bf.Deserialize(cs), BindingList(Of Animal))
End Using
End Using
' test:
For Each a As Animal In mcol
Console.WriteLine(a.Name)
Next
我的所有动物都在旅途中幸存下来:
流动站
小玩意儿
Ziggy
主要的事情似乎是您使用了太多的流。在你的解密器中,你试图从一个与读取文件的cryptostream无关的memstream反序列化。事实上,它刚刚创建了这条线。 cryptostream基本上只包含你正在使用的“真实”流。
此外,此行显示您未使用Option Strict
:
photoJobs = formatter.Deserialize(memStreamSerial)
Deserialize
返回一个对象,而photoJobs
是来自过去帖子的某种集合IIRC。请注意,我的代码使用CType
转换为BindingList(Of Animal)
。
使用Option Strict
比'Hello,World`更复杂。总是。
从密码中导出(哈希)IV是一个坏主意:这些应该是独立的数据。对于每个数据(对于重用PW而言不是这种情况)和唯一的IV,IV应该是唯一的。我在PW中添加了一些任意文本,以便MD5哈希不是直接从
其次,MD5已经过时了。
创建随机IV
Private Const MinSize = 7
Public Shared Function GetRandomBytes(size As Integer) As Byte()
' dont allow less than a sensible min
Dim data(If(size < MinSize, MinSize, size)) As Byte
Using rng As New RNGCryptoServiceProvider
' fill the array
rng.GetNonZeroBytes(data)
End Using
Return data
End Function
将它放在加密工具库中,因为你将它用于IV以及Salt用于哈希。例如:
myIV = CryptoUtils.GetRandomBytes(15)
如果IV每次都是唯一的,那么诀窍就是如何保存它,因此可以在解密中使用相同的值。 IV不必是秘密的,因此可以在将其传递给FileStream
构造函数之前将其保存到CryptoStream
。 Decrypt方法正好相反。
这些也可以制成方法,因此每次都使用相同的过程。
最后,如果问题更加简洁,您的问题将得到更好的接受。该错误清楚地表明了加密问题,因此前两个块的噪声或多或少。