Stream Composition Examples

This page continues with code examples based on the code shown on the Serialization Examples page.

Composing Compression

Compressing a value is just another stream operation, as follows:

// "instance1" represents any serializable object.
// Example only, keys are typically known unique business values:
var key = "mykey#binaryCompressed";

// Save the compressed value:
var valueHandle1 = new ValueHandle(key);
using (var c = new SqlConnection(connectionString))
using (var s = valueHandle1.GetWriterStream(c))
using (var gzip = new GZipStream(s, CompressionLevel.Fastest))
{
    var formatter = new BinaryFormatter();
    formatter.Serialize(gzip, instance1);
}

Decompression is the same usage pattern:

BinaryDataObject instance2;
using (var c = new SqlConnection(connectionString))
using (var r = valueHandle2.GetReaderStream(c))
using (var gzip = new GZipStream(r, CompressionMode.Decompress))
{
    var formatter = new BinaryFormatter();
    instance2 = formatter.Deserialize(gzip) as BinaryDataObject;
}

Composing Encryption

Encryption and decryption is more involved from the perspective of properly securing secrets and using the .NET encryption API's properly. Below shows an example usage that conveniently ignores secret management complexities, to the point that interacting with the Key Value store doesn't make this any more or less complex:

// Example only, keys are typically known unique business values:
var key = "exampleKey#encryptedUsage";
            
// Set up crypto provider. The init vector and keys 
// are normally protected secrets. this example uses 
// the storage key as the encryption key:
var cryptoProvider = new RijndaelManaged();
cryptoProvider.IV = new byte[16] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
cryptoProvider.Key = SHA256Cng.Create().ComputeHash(Encoding.UTF8.GetBytes(key));

var encryptor = cryptoProvider.CreateEncryptor(cryptoProvider.Key, cryptoProvider.IV);
var decryptor = cryptoProvider.CreateDecryptor(cryptoProvider.Key, cryptoProvider.IV);

// Initial save, don't provide a version number:
var valueHandle1 = new ValueHandle(key);
using (var c = new SqlConnection(connectionString))
using (var s = valueHandle1.GetWriterStream(c))
using (var cryptoStream = new CryptoStream(s, encryptor, CryptoStreamMode.Write))
{
    var formatter = new BinaryFormatter();
    formatter.Serialize(cryptoStream, instance1);
}

// Initial get, don't provide a version number.
var valueHandle2 = new ValueHandle(key);

BinaryDataObject instance2;
using (var c = new SqlConnection(connectionString))
using (var r = valueHandle2.GetReaderStream(c))
using (var cryptoStream = new CryptoStream(r, decryptor, CryptoStreamMode.Read))
{
    var formatter = new BinaryFormatter();
    instance2 = formatter.Deserialize(cryptoStream) as BinaryDataObject;
}

Last edited Feb 25, 2015 at 5:35 PM by bkjuice, version 5