Some of us grew up in small towns with relatively few people around and didn’t feel the need to lock our doors. As populations grew and we moved to bigger cities, the need to keep doors locked increased.
In the days of old, some 20 years ago, when PCs were first emerging and few people understood the ‘rocket science’ of an OS command prompt, there was little need in business for digital security and data encryption because only a trusted few knew how to access the stored data and programs within. Fast forward to today where an Internet connection and a networked PC on every desk is the defacto standard of doing business, and the need for greater levels of digital security becomes just as defacto.
And while you might hire one of the neighbors’ kids to mow the lawn around your house in the big city, you would still hire a qualified security company to protect your home and detect intruders. Likewise, your junior programmers are probably ill-equipped to develop all the cryptography modules for your company or clients.
So what’s a Blowfish and why is it relevant here? Blowfish is the name of a publicly available block data encryption algorithm developed by Bruce Schneier. It is a small and fast symmetric encryption scheme that uses a variable length key that can be up to 448 bits long. It is considered safe and there are no known successful attacks against it.
That’s great, but should you use it? What about the key size? Don’t you need 1024-bit keys to be really secure these days? Not necessarily, because there is a tradeoff with larger keys. Also, your application may not require that degree of security (in this case defined as the length of time your secret data needs to remain that way) and would be adversely affected by usage of a larger key. For a vast majority of applications (including HIPAA compliance) the 448 bit max Blowfish key is already significant overkill.
A concern much greater than that of key size is key security. By far, the greatest risks to any data encryption scheme are the human factors. For any key sizes that exceed 56 bits in a symmetric algorithm, it is far easier to simply steal the keys or buy them from one of your trusted employees than to take the time and money to develop and run the system necessary to break your encryption without the keys.
Blowfish is best suited for applications where keys remain relatively constant such as communications links and embedded file encryption. Also, since it is a symmetric algorithm, it suffers from the same key exchange problems as all the other symmetric algorithms. Public key algorithms such as Diffie-Hillman are available that work better in those applications (and as a side note, it’s the public key algorithms that commonly need the much larger key sizes).
So is Blowfish right for you? Perhaps, but without first investigating your precise needs i.e. what kind of data needs protection, who needs to access the data, where it will be stored, etc., it is impossible to know just what is right. Gather your thoughts about your needs and then contact a professional to develop a secure and workable solution. save your loans at payday advance
When using the MSXML2 library, you typically load XML files from disk into a DOM (Document Object Model) object by creating an instance of IXMLDOMDocument and calling its load function—where you pass a BSTR representation of the file name. However, I had a situation recently where, due to security concerns, I needed to first decrypt the XML data in memory and then load that memory—without writing it to disk—into a DOM object. Surprisingly, I wasn’t able to find any open source examples of how to do this so I wrote a couple of helper functions to accomplish the task. Hopefully, these functions will help others that run into a similar situation.
Since Bruce Schneier introduced the Blowfish encryption algorithm in 1993, its had many implementations. I’ve personally found George Anescu’s work to be especially easy to use in scenarios where I’ve needed fast and reliable means of encrypting and decrypting data. Therefore, my functions work with data that is encrypted using his CBlowFish class.
The first thing I learned when searching for a solution is that the IXMLDOMDocument object supports a function called loadXML, which takes a BSTR value representing the XML to parse. Since I like to keep the client side as easy and clean as possible, I wanted the client to call a single function that would pretty much do everything. As a result, I created the DecryptFile2Bstr function, which takes an input file name and password (both char pointers) and returns a BSTR that can then be used with the IXMLDOMDocument::loadXML function:
BSTR DecryptFile2Bstr(char* inputFileName, char* password)
{
try
{
int requiredFileSize;
CBlowFish oBlowFish((unsigned char*)password, sizeof(password));
char *buffer = GetFormattedFileContent( inputFileName, requiredFileSize );
oBlowFish.Decrypt((unsigned char *)buffer, requiredFileSize);
return _com_util::ConvertStringToBSTR(buffer);
}
catch ( char *ex )
{
throw ex;
}
}
As you can see, the DecryptFile2Bstr function instantiates a CBlowFish object and then calls another helper function I wrote, GetFormattedFileContent, before invoking the CBlowFish::Decrypt function. As the data used by both the GetFormattedFileContent and CBlowFish::Decrypt functions is in the form of a char buffer, the DecryptFile2Bstr function calls the standard COM utility function ConvertStringToBSTR before returning to the caller.
The Blowfish algorithm is based on eight-byte blocks, so the GetFormattedFileContent function reads the data into memory accordingly. Note the padding at the end of the function to accommodate this rule:
char* GetFormattedFileContent(char *filePath, int &requiredFileSize)
{
FILE *fp = fopen(filePath, "r+b");
int fileSize = FileSize(fp);
int index = fileSize;
if ( (fileSize %
!= 0 )
requiredFileSize = ((fileSize /
+ 1) * 8;
else
requiredFileSize = fileSize;
char *buffer = new char[requiredFileSize + 1];
fread(buffer, sizeof(char), fileSize, fp);
buffer[fileSize] = 0;
fclose(fp);
while (index < requiredFileSize)
buffer[index++] = 0;
return buffer;
}
int FileSize(FILE *fp)
{
char buffer[1];
int count = 0;
fseek(fp, 0, SEEK_SET);
while (fread(buffer, sizeof(buffer), 1, fp) != 0) count++;
fseek(fp, 0, SEEK_SET);
return count;
}
Using the DecryptFile2Bstr Function
Assuming your data has been encrypted using the CBlowFish class, you can load it into an XML DOM object with two lines of code:
#import <msxml4.dll> named_guids
using namespace MSXML2;
...
::CoInitialize(NULL);
MSXML2::IXMLDOMDocumentPtr plDomDocument;
HRESULT hr = plDomDocument.CreateInstance(MSXML2::CLSID_DOMDocument);
if (SUCCEEDED(hr))
{
// load the file as an XML document
BSTR xmlfile = DecryptFile2Bstr(L"MyFile.xml", DEFS_ENC_PASSWORD);
variant_t vResult = plDomDocument->loadXML(xmlfile);
...
Looking Ahead
Combining the MSMXL2 IXMLDOMDocument::loadXML with my helper functions, I was able to read the client’s sensitive data into memory and decrypt it without first having to decrypt it to disk. I’ve also extended these functions to include other helper functions that perform such tasks as decrypting a file with CBlowFish-encrypted data to a specified file (DecryptFile2File) and encrypting plain ASCII data to a CBlowFish-encrypted file (EncryptFile2File). If you have any need or interest in these functions, email me and I’ll also post them for public use.