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]
{
    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;
    }
}

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;
}

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.


Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in .NET, C#, Data Access. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://gabrielrodriguez.net Gabriel Rodriguez

    Very nice and simple way to solve your problem. Thanks for sharing…might end up using it some day.

  • http://thechroniclesofvinh.com Vinh

    Nice piece of code, Derick. Found you from Matt Sell’s blog mentioned on S.O.L.I.D.

    Two things to consider:

    1) Since desired functionality is to obfuscate the persisted data to file, encoding it in memory is a performance hit. Perhaps only encode/decode when writing to or reading from file.

    2) Encoded key/value pairs in memory are not debugging friendly.

    It’s been a while, man. Congrats on your sucess!

    vinh.