Hiding Sensitive Information With A Base64 Encoded Dictionary And Binary Serialization


I’ve been back in C# land for the last few weeks writing a small Winforms application that runs from a USB thumb drive.

Need To Hide Some Data?

We have a need to store some slightly-sensitive information that changes whenever the app has an internet connection and is able to download updates. It’s nothing that needs true security with encryption, username & password, or anything like that. And there’s no existing database / data access in the app, so we don’t have a password protected database to dump it in, either.

We thought about several different options to handle our needs:

  • Ignore the possibility of someone reading / modifying the data. It’s not likely, and not super critical. Probably not a good choice.
  • Use a simple database like db4o or sqlite. Too much setup and extra work since we don’t need data access anywhere else.
  • Use .NET’s Isolated Storage. Great idea, but we can’t store data based on user. Any user with the thumb drive has to be able to get to it.
  • Real encryption / decryption and writing to a file. This is probably the best idea, honestly. The code to encrypt / decrypt a string isn’t that bad.

Given the simple needs of the situation, I found it was easiest to build a custom Dictionary class that base64 encodes all of the keys and values, and is able to read / write itself to a binary serialized file. It’s a simple chunk of code and it provides a small amount of information hiding that suits our needs just fine. If you do need a little more security, you could easily replace the base64 encode/decode with some type of encrypt/decrypt.

A Base64Dictionary With Binary Serialization

The class is inheriting from a Dictionary<string, string> and I’m only overwriting the indexer because I’m not using any other methods to get data into or out of the dictionary at this point.

public string this[string key]

</div>

{
get
{
var encoded_key = Convert.ToBase64String(Encoding.UTF8.GetBytes(key));
var encoded_value = base[encoded_key];
return Encoding.UTF8.GetString(Convert.FromBase64String(encoded_value));
}
set
{
var encoded_key = Convert.ToBase64String(Encoding.UTF8.GetBytes(key));
var encoded_value = Convert.ToBase64String(Encoding.UTF8.GetBytes(value));
base[encoded_key] = encoded_value;
}
}

</pre> </blockquote>

I also have a WriteTo(file) and ReadFrom(file) method set up. This is where the binary serialization / deserialization occurs.

public void WriteTo(string file)
{
IFormatter formatter = new BinaryFormatter();
using (Stream stream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None))
{
formatter.Serialize(stream, this);
}
}
public static Base64Dictionary ReadFrom(string file)
{
Base64Dictionary obj;
IFormatter formatter = new BinaryFormatter();
using (Stream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
obj = (Base64Dictionary) formatter.Deserialize(stream);
}
return obj;
}
</blockquote>

Note that the ReadFrom(file) method is a static method. This lets you call Base64Dictionary.ReadFrom(file) directly and not have to instantiate a Base64Dictionary object first. The only other detail is to include the [Serializable] attribute and a deserialization constructor. After that, you can start writing and reading binary serialized files that hide the data in them a little.

No, It’s Not Secure

Remember, this is not a secure way of storing critical data. It’s only meant to hide the data from prying eyes. Anyone with half a sense of code could easily figure out the data is base64 encoded and decode it, gaining access to it.

For the complete code, including a simple example of using it, see this gist.

Good Refactoring / Patterns For Simple UI Logic?