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.