簡體   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