Note: On May 19, 2005, DES (FIPS 46-3) was withdrawn, and is no longer approved for Federal use.

The underlying Cryptographic library is Wei Dai'sCrypto++. If required, Crypto++ is FIPS 140-2 conformant. Using the conformant version of the library requires the programmer to load the library as a DLL.

Other cryptographic libraries exist, such as Peter Guttman'sCryptlib. The reader is encouraged to modify the program presented in this article to include other libraries.

Background

Windows maintains a secure area of the Registry called the SAM (Security Accounts Manager). Users, administrators, and programmers are generally not permitted access to this area of the Registry directly. One must use API functions such as the LSA family, or tools such as User Manager for Domains or Active Directory Users and Computers.

To allow programmers to securely save data to the Registry (but not the SAM), a programmer can use CAESEncRegKey. However, there are a few limitations that one must observe when using the Registry. The most important for the purposes of this article is limiting binary data (value type REG_BINARY) size at or below 2048 bytes. See Microsoft's Registry Element Size Limit in MSDN.

Downloads

This article includes four downloads:

GUI demo

CLI demo

Source Code

Key and IV Generator Program

The GUI demo is a release build demonstration that exercises the CAESEncRegKey class. The CLI (command line) demo is an AES proof of concept using the Crypto++ library. It simply demonstrates the Crypto++ AES Encryption/Decryption process.

The Key and IV Generator program uses the Crypto++ AutoSeededRandomPool PRNG to create pseudo random values for the Key and IV vectors.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment

An AES Encrypting Registry Class

Understanding the Crypto++ Encryption/Decryption Process

One of the easiest ways to approach this class file is by inspecting the CLI demo (shown below). The code performs the following:

Construct a AES::Encryption object (seeded with a Key).

Construct a CBC_Mode_ExternalCipher::Encryption object (seeded with an encryptor (AES::Encryption), and an IV).

Construct a StreamTransformationFilter for buffering and padding (seeded with a cipher (CBC_Mode_ExternalCipher::Encryption) and std::string).

Push the plain text into the StreamTransformationFilter (which places the encrypted text in ciphertext).

When encrypting the string, length( ) + 1 is used so that the trailing '\0' is captured (used later for decryption). The encrypted text is available in the std::string object ciphertext. Because the ciphertext may have embedded '\0' characters, use member functions std::string::size( ) or std::string::length( ) rather than std::strlen( ). SGI states that std::string::length( ) is synonymous with std::string::size( ). The raw data can be accessed through the std::string::c_str( ) or std::string::data( ) function. See the SGI documentation for basic_string for a detailed discussion of the functions.

Decryption is simply the reverse of encryption, using AES::Decryption and CBC_Mode_ExternalCipher::Decryption objects.

CAESEncRegKey Class

The CAESEncRegKey includes member functions for reading and writing of both encrypted and unencrypted data. The supported registry value types are REG_BINARY, REG_DWORD, and REG_SZ. The following will discuss the operation of writing and reading of an encrypted string. DWORD and Binary data are similar.

The class also contains data members for stateful representation of the following. Generally, most will not change once set. The exception is ValueName, which changes as multiple data is read and written.

AES Key

AES IV

HKEY

SubKey

ValueName

AES Key and AES IV are struct to simplify operations. SubKey and ValueName are CStrings.

In keeping with the spirit of Microsoft's Registry APIs, all functions have a return value type of LONG.

CAESEncRegKey Encryption

The steps for writing an encrypted string are as follows:

WriteString(...)

WriteEncString(...)

EncryptData(...)

WriteNonEncBinary(...)

Below is the WriteString(...) function. It will defer to WriteEncString(...) or WriteNonEncString(...) as required.

WriteNonEncString(...) simply acts like any other Registry Class—it writes the string to the Registry. Note that RegCreateKeyEx(...) is used to open keys for writing because RegCreateKeyEx(...) will either create the key or open an existing key.

WriteEncString(...) is coded as follows. Note that two operations occur:

The string is encrypted using earlier code by way of EncryptData(...).

WriteNonEncBinary(...) performs the Registry write, as if it were simply called to write unencrypted binary data. WriteNonEncBinary(...) will be called frequently because writing data that has already been encrypted is that same as writing non-encrypted data.

An AES Encrypting Registry Class

CAESEncRegKey Decryption

The steps for reading an encrypted string are as follows:

ReadString(...)

ReadEncString(...)

ReadData(...)

DecryptData(...)

The ReadEncString(...) function calls ReadData(...), which returns the binary data and size of the encrypted string. It is ReadEncString(...)'s responsibility to free it. Also note that ReadData(...) opens the key using RegOpenKeyEx(...); the key is not created if missing.

Once the encrypted data is available, DecryptData(...) is called. Again, the DecryptData(...) function simply decrypts the data using AES::Decryption and CBC_Mode_ExternalCipher::Decryption objects.

Finally, when reading data, CAESEncRegKey mimics the functionality of RegQueryValueEx(...) by returning ERROR_SUCCESS or ERROR_MORE_DATA depending on the cbBuffer and cbSize arguments. See RegQueryValueEx in MSDN for a detailed explanation. Below is a sample from ReadEncBinary(...). Note that the data must be read from the Registry, and then decrypted before the buffer size can be determined.

Using CAESEncRegKey

CAESEncRegKey not only provides functions for reading and writing of registry value types, it also provides mutators and accessors for changing the Registry Key object. As stated earlier, two helper structures are used to manage the AES Key and AES IV. The structures are declared and defined in aeshelper.h.

If that fails, uncomment the appropriate #pragma statement in stdafx.h. See Carl Daniel's comment on the error from Google's Usenet archive.

History

11/14/2006: Updated Crypto++ Link

11/14/2006: Updated Article Graphics

10/10/2005: Initial Release

About the Author

Jeffrey Walton

In the past, I have worked as an IT consultant for County Government (Anne Arundel County), the Nuclear Energy Institute, the Treasury Department, and Social Security Administration as a Network Engineer and System Administrator. Primary Administration experience includes Microsoft Windows and Novell Netware, with additional exposure and familiarity with Mac and Linux OSes.
Previous to the US government, I was a programmer for a small business using Microsoft Visual Languages (Basic 5.0, 6.0, and C++ 5.0, 6.0) and Scripting Languages.
An undergraduate degree (BS in Computer Science) was obtained from University of Maryland, Baltimore County. Graduate work includes a Masters of Science (Computer Science) from Johns Hopkins University (expected before 2009).
Training and Certifications include Microsoft, Checkpoint, and Cisco.

Top White Papers and Webcasts

U.S. companies are desperately trying to recruit and hire skilled software engineers and developers, but there is simply not enough quality talent to go around. Tiempo Development is a nearshore software development company. Our headquarters are in AZ, but we are a pioneer and leader in outsourcing to Mexico, based on our three software development centers there. We have a proven process and we are experts at providing our customers with powerful solutions. We transform ideas into reality.

When individual departments procure cloud service for their own use, they usually don't consider the hazardous organization-wide implications. Read this paper to learn best practices for setting up an internal, IT-based cloud brokerage function that service the entire organization. Find out how this approach enables you to retain top-down visibility and control of network security and manage the impact of cloud traffic on your WAN.