Live Journal about blowfish |

Can AES Encryption be Cracked?

Apart from social engineering exist two ways to break an encryption key like AES, brute force and cryptanalysis. Find out here whether AES encryption can be cracked any time soon, along with the latest AES development and recommendations from IT security evangelist Bruce Schneier.

Besides social engineering exist two ways to break any encryption key, brute force and cryptanalysis. After the introduction we look at why AES and similar encryption schemes are secure against brute-force attacks using computer power to crack a key. Then you will find the latest development from the studies of AES by means of cryptanalysis. If you are not familiar with encryption it is recommended reading Bright Hub’s article What is AES Encryption? and Types of Encryption.

Brute Force

Mathematicians have discovered that any positive integer greater than one can be expressed as the product of its prime factors; the prime decomposition of the number 22 for instance is 2 x 11. There are a number of algorithms for integer factorization, but the difficulty and complexity to find the prime factor increases at the last sub-exponentially with the size of the integer.

This essentially means that the prime decomposition of large numbers is computationally infeasible with traditional computers. As the strongest encryption algorithms in use today, such as, for instance, Rijndael, which has become the Advanced Encryption Standard (AES), employ large integer factorization, AES in unbreakable – again with the premise of traditional computers in mind.

A quantum computer operating on qubits instead of bits offer polynomial speed for some computing problems including Integer factorization, so that taking into account Cobham’s thesis we know that the traditional encryption algorithm keys can be feasibly computed. Therefore, when quantum computing gets out of the lab will ciphertext produced by traditional cryptography no longer be secure.

Cryptanalysis

The Advanced Encryption Standard can be used with 256-bit keys, immune against Moore’s Law for the years to come. However, cryptanalysts studying the inner working of an algorithm are constantly trying to find a weakness in the encryptions algorithms or to break it. Most “vulnerabilities” are usually of rather theoretical nature, so there is nothing to worry about for an ordinary computer user as the subject is being watched and followed by the IT security community which has been trying to crack publicly documented encryption schemes including AES for years.

Yet, it was only recently when Bruce Schneier, the inventor of Twofish and Blowfish AES competitors stipulated “that the safety margin of AES is much less than previously believed [1].” Schneier demands that AES implements more round of Rijndael for any key length “and for new applications I suggest that people don’t use AES-256. AES-128 provides more than enough security margin for the foreseeable future


Loading Blowfish-Encrypted Data into an MSXML2 DOM Object

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 % 8) != 0 )
    requiredFileSize = ((fileSize / 8) + 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.