繁体   English   中英

如何将文本数据保存到二进制文件中以使其不可读

[英]how do you save text data into binary file to be unreadable

好吧,我只是无法在网上找到一个很好的简单示例来帮助我实现自己的目标,而不必学习有关vbnet中某个主题的全新的新章节。 我想保存重要的“设置”,例如管理密码,用户计算机可以使用这些设置来从他们的计算机访问远程服务器。

在我有程序的示例中,只要数据不是文本(例如“ This is my password”)但不会显示诸如1232.78或布尔值的数字,该程序就可以正常运行

使用记事本可以轻松地从文件中读取纯文本(即字符串)。

有没有一种方法可以避免显示在二进制文件中明显可见的文本数据?

      Imports System
      Imports System.IO
      Public Class Form2

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


    Const fileName As String = "AppSettings.txt"

    Using writer As BinaryWriter = New BinaryWriter(File.Open(fileName, FileMode.Create))
        writer.Write("This is my secret password")
        writer.Write(1.25F)
        writer.Write("c:\Temp")
        writer.Write(10)
        writer.Write(True)
    End Using



 End Sub

 end class

当我用记事本打开文件AppSettings.txt时,它显示

              This is my secret password   ?c:\Temp

以及其他一些无法在此处显示的字符。 当我读取文本文件时,文本文件中的所有数据均会正确读取。

那么,如何使程序用户看不到二进制文本文件的可读信息?

写入二进制文件时,文本不会被混淆。 从技术上讲,您看到的作为奇数字符的数字也不是不可读的-如果有人知道数据类型,他们可以算出值。

为了使它不可读,您可以一个一个地加密每个字符串(如建议的dupe链接中所述),或将您的流“包装”在Cryptostream 由于您希望BinaryWriter为您执行一些伪加密,因此可以完全跳过它。 另一种选择是将信息存储在一个类中,并使用CryptoStream对其进行序列化以将其写出。

下面的代码使用一个类来保存这些各种设置,并使用BinaryFormatter来序列化该类。 串行器将避免必须逐位写出数据,并且如果您要扩展或更改要保存的数据,只需修改类,而不是密码即可。 服务器信息类:

<Serializable>
Public Class SvrSettings
    Public Property Server As String
    Public Property UserName As String
    Public Property Password As String

    Public Property SomeInt As Int32
    Public Property SomethingElse As DateTime
    ' add anything else to be encrypted
End Class

' elsewhere put the data to save/encrypt in an instance:
SvrData = New SvrSettings
SvrData.UserName = "admin"
SvrData.Password = "some password"
SvrData.SomeInt = 42
SvrData.SomethingElse = DateTime.Now
SvrData.Server = "addressof(mysvr)"

保存到加密的二进制文件。 您将需要一些新的导入:

Imports System.Security.Cryptography
Imports System.Runtime.Serialization.Formatters.Binary
'...
Dim password As String = "AWeakPassword"

Dim key As Byte() = Encoding.UTF8.GetBytes(password)
Dim iv(15) As Byte
    Using rng As New RNGCryptoServiceProvider
    rng.GetNonZeroBytes(iv)
End Using

Using rijAlg = Rijndael.Create()
    rijAlg.Padding = PaddingMode.ISO10126

    ' USING encryptor AND filestream
    Using encryptor As ICryptoTransform = rijAlg.CreateEncryptor(key, iv),
            fs As New FileStream("C:\Temp\crypto.bin",
                                 FileMode.OpenOrCreate Or FileMode.Truncate)
        ' save iv to "naked" filestream
        fs.Write(iv, 0, iv.Length)
        Using cs As New CryptoStream(fs, encryptor, CryptoStreamMode.Write)
            Dim bf As New BinaryFormatter
            bf.Serialize(cs, SvrData)
            ' may not be needed - doesnt hurt
            cs.FlushFinalBlock()
        End Using
    End Using
End Using

序列化意味着一次存储该类中的所有数据。 CryptoStream包装FileStream并进行实际的加密。

您将需要iv来读回数据,而不必将其存储在某个地方,而是在将数据包装到CryptoStream之前将其写入文件流。 读回:

' read back to a new instance
Dim newSvrData As SvrSettings

Using rijAlg = Rijndael.Create()
    rijAlg.Padding = PaddingMode.ISO10126

    Using fs As New FileStream("C:\Temp\crypto.bin", FileMode.Open)
        ' read the IV first
        fs.Read(iv, 0, iv.Length)
        ' USING encryptor AND CryptoStream
        Using encryptor As ICryptoTransform = rijAlg.CreateDecryptor(key, iv),
            cs As New CryptoStream(fs, encryptor, CryptoStreamMode.Read)
            Dim bf As New BinaryFormatter
            newSvrData = CType(bf.Deserialize(cs), SvrSettings)
        End Using
    End Using
End Using

' test if the data made the round trip:
Console.WriteLine(newSvrData.UserName)
Console.WriteLine(newSvrData.Password)
Console.WriteLine(newSvrData.Server)
Console.WriteLine(newSvrData.SomethingElse)

检测结果:

管理
一些密码
addressof(MYSVR)
2016/2/6下午13:56:44

通过将其包装在CryptoStream ,可以对二进制CryptoStream执行类似的操作。 序列化对象的价值在于保存所有值只是一行代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM