Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Tutorial 2: Symmetric Encryption For File I/O

Overview

MynahSA provides input and output streams that are encrypted using OpenSSL's implementation of Counterpane's Blowfish cipher. Using the Mynahsa::IBlowfishStream and MynahSA::OBlowfishStream classes data can be encrypted on disk files or std::streams.

Strong encryption is particularly helpful for applications where your data needs to be secure - this mechanism enforces security because data cannot be read or written without encryption.

Unlike simple password protections that prevent a file from being loaded, files stored with the Blowfish stream are completely encrypted. Barring an attack on Blowfish or knowing the password it is extremely unlikely that the data will be extracted from an encrypted file.

Usage

The Blowfish streams are used similarly to the standard input/output streams presented in Tutorial 1: Simple Object Persistence, however, a password must be supplied to the class constructor.

To demonstrate the use of the Blowfish streams, a simple C++ struct will be archived. Three steps will be performed: The data structure definition is the following:
struct SimpleContainer { 
  void serialize(Archive&amp ar) { 
    ar &amp _name;
    ar &amp _age;
  }

  string _name;
  int _age;
};
The first step is to create an instance of the SimpleContainer and fill it with some data, then store it onto an output Blowfish stream using the password "Private Key".
ostringstream ostr;
{ 
  SimpleContainer sc;
  sc._name = "Brett";
  sc._age = 32;
    
  OBlowfishStream obfs(ostr, "Private Key");
  OArchive<OBlowfishStream&gt oabfs(obfs);
   
  oabfs << sc;
}
To examine the data on the stream each character is displayed it as an integer; preventing control characters from affecting the console.
for (unsigned int i=0; i&lt;ostr.str().size(); i++) { 
  unsigned char ch = ostr.str()[i];
  cout << "Stream[" << i << "] contains value: " << ((unsigned int) ch) 
       << endl;
}
cout << endl;
This produces the output:
Stream[0] contains value: 203
Stream[1] contains value: 41
Stream[2] contains value: 151
Stream[3] contains value: 189
Stream[4] contains value: 126
Stream[5] contains value: 126
Stream[6] contains value: 5
Stream[7] contains value: 196
Stream[8] contains value: 1
Stream[9] contains value: 25
Stream[10] contains value: 102
Stream[11] contains value: 51
Stream[12] contains value: 198
Stream[13] contains value: 26
Stream[14] contains value: 149
Stream[15] contains value: 212
These numbers are garbled and exactly what is expected from an encryption routine.

To decrypt and restore the object state the exact opposite process is performed:
{
  SimpleContainer sc;
  istringstream istr(ostr.str());
  IBlowfishStream ibfs(istr, "Private Key");
  IArchive&lt;IBlowfishStream&gt iabfs(ibfs);
  iabfs >> sc;
  cout << "sc's name: " << sc._name << endl;
  cout << "sc's age: " << sc._age << endl; 
}
Which produces the expected results:
sc's name: Brett
sc's age: 32

Notes