简体   繁体   English

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

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

Well i just cannot find a good simple example all over the net to help me achieve my aim without having to learn some whole new chapter on some topic in vbnet. 好吧,我只是无法在网上找到一个很好的简单示例来帮助我实现自己的目标,而不必学习有关vbnet中某个主题的全新的新章节。 I want to save crucial "settings" such as administrative password that can be used by user computer to access a remote server from their computer. 我想保存重要的“设置”,例如管理密码,用户计算机可以使用这些设置来从他们的计算机访问远程服务器。

In the example that i have the program works ok as long as data is not text such as "This is my password" but will not reveal numbers like 1232.78 or boolean values 在我有程序的示例中,只要数据不是文本(例如“ This is my password”)但不会显示诸如1232.78或布尔值的数字,该程序就可以正常运行

Plain text ie strings can be read easily from file using notepad. 使用记事本可以轻松地从文件中读取纯文本(即字符串)。

Is there a way to avoid showing of text data being obviously visible in binary files? 有没有一种方法可以避免显示在二进制文件中明显可见的文本数据?

      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

When i open my file AppSettings.txt with notepad it shows 当我用记事本打开文件AppSettings.txt时,它显示

              This is my secret password   ?c:\Temp

with some other characters that cannot show here. 以及其他一些无法在此处显示的字符。 When i read text file all data in text file reads correctly. 当我读取文本文件时,文本文件中的所有数据均会正确读取。

So how do i get program user not to see the human readable information of binary text files? 那么,如何使程序用户看不到二进制文本文件的可读信息?

Text doesnt get obfuscated when written out to binary. 写入二进制文件时,文本不会被混淆。 Technically, the numerics which you see as odd characters are not unreadable either - if someone know the datatype they could work out the values. 从技术上讲,您看到的作为奇数字符的数字也不是不可读的-如果有人知道数据类型,他们可以算出值。

To make it non readable, you could encrypt each string one by one (as in the proposed dupe link), or "wrap" your stream in a Cryptostream . 为了使它不可读,您可以一个一个地加密每个字符串(如建议的dupe链接中所述),或将您的流“包装”在Cryptostream Since you were hoping the BinaryWriter would do some pseudo encryption for you, you could skip it entirely. 由于您希望BinaryWriter为您执行一些伪加密,因此可以完全跳过它。 Another alternative is to store the info in a class and serialize it using a CryptoStream to write it out. 另一种选择是将信息存储在一个类中,并使用CryptoStream对其进行序列化以将其写出。

The code below uses a Class to hold these various settings and the BinaryFormatter to serialize the class. 下面的代码使用一个类来保存这些各种设置,并使用BinaryFormatter来序列化该类。 The serializer will prevent having to write out the data bit by bit, and if you ever extend or change the data to be saved, just modify the class, not the crypto code. 串行器将避免必须逐位写出数据,并且如果您要扩展或更改要保存的数据,只需修改类,而不是密码即可。 A server info class: 服务器信息类:

<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)"

Save to encrypted binary file. 保存到加密的二进制文件。 You will need some new Imports: 您将需要一些新的导入:

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

Serializing means that all the data in that class is saved all at once. 序列化意味着一次存储该类中的所有数据。 The CryptoStream wraps the FileStream and does the actual encryption. CryptoStream包装FileStream并进行实际的加密。

You will need the iv to read the data back, but rather than having to store it somewhere, this writes it to the filestream before it is wrapped in the CryptoStream . 您将需要iv来读回数据,而不必将其存储在某个地方,而是在将数据包装到CryptoStream之前将其写入文件流。 To read it back: 读回:

' 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)

Test results: 检测结果:

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

You could do something similar with your binary writer by wrapping it in a CryptoStream . 通过将其包装在CryptoStream ,可以对二进制CryptoStream执行类似的操作。 The value of serializing an object is that it is just one line of code to save all the values. 序列化对象的价值在于保存所有值只是一行代码。

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

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