简体   繁体   中英

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. 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

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

              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 . Since you were hoping the BinaryWriter would do some pseudo encryption for you, you could skip it entirely. Another alternative is to store the info in a class and serialize it using a CryptoStream to write it out.

The code below uses a Class to hold these various settings and the BinaryFormatter to serialize the class. 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.

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 . 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)
2/6/2016 13:56:44 PM

You could do something similar with your binary writer by wrapping it in a CryptoStream . The value of serializing an object is that it is just one line of code to save all the values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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