Figure 1 Secure Pocket Store
In my first article for The Code Project, I was simply curious on how to start writing a real world application for the Pocket PC using C#. Now I was wondering whether I could develop an easy to use cryptographically strong data store keeping my digitalized secrets on my Pocket PC. But how are you treating your secrets which are worth enough to be hidden for prying eyes, like passwords, accounts, identities, PINs and stuff like that? Of course, you can either memorize them all or buy some serious award winning product like eWallet to keep them all. For me however, being a developer, it was rather challenging to create such a store using Visual Studio .NET. So you are invited to learn along with me to use the Microsoft Enhanced Cryptographic Service Provider in a .NET Compact Framework application.
Let's first define the major cryptographic requirements an application of such a sensitive context has to fulfill in order to be secure enough. It has to guarantee high level protection against cryptanalysis and direct brute-force breaking attacks in case of loss or theft.
- The secret data written to a file should be encrypted with a strong industrial standard algorithm using at least a 128 bit symmetric key.
- The symmetric key has to be created each time based on the user's memorized pass phrase.
- The encrypted data file must not contain well known list of predefined words and sequences of predictable characters.
- The application has to exit automatically being idle after a couple of minutes.
- The exiting application must not leave secrets in the memory.
- It is forbidden to write plain text data into a data file.
If you are not familiar with cryptography at all, jump start reading Neal Stephenson's Cryptonomicon. The book is not just thrilling but gives also some real hints about the methods hackers are using to break encrypted messages. Cryptanalysis is an advanced art of breaking cryptosystems, it is the process of looking for weaknesses in the implementation. A special method in cryptanalysis is based on prior knowledge and assumptions the unencrypted plain text probably contains. Thus an approach which would simply use an encrypted valid XML document with a well known predefined schema is probably a bad idea, as such an encrypted file contains a plenty of predictable character sequences (XML element names).
Pondering how to start to develop my application, I have first hoped the
System.Security.Cryptography classes are also supported in the .NET Compact Framework which I was familiar with. Unfortunately, they are not! Therefore I was forced to look whether I can figure some example using P/Invoke in order to reach the Microsoft Cryptographic Service Provider (MCSP) functions. Fortunately, there is an article on MSDN: Pocket PC Signature Application Sample from Ralph Arvesen. This article contains a custom
Crypto class, which offers nearly everything I was looking for. I have made minor changes and extensions to adapt this class for my needs, which are as follows:
- The original
Crypto class used the Microsoft Base Cryptographic Service Provider (MBCSP) which is based on relatively weak (40 bit) keys. I extended the class using instead the Microsoft Enhanced Cryptographic Service Provider (MECSP) offering much longer keys (128 bit).
- I also extended the
Crypto class with initialization vector (IV) functionality. This was achieved by declaring two additional
DllImports incorporating the
CryptSetKeyParam() and the
- Next, I extended the class with the overridden
Decrypt methods referring also to the initialization vector. I will explain to you later on why an IV is important.
Considering the availability of MECSP symmetric encryption algorithms (DES, Triple DES, RC2, RC4), I decided to use the industry standard RC2 block encryption algorithm with cipher block chaining and 128 bit key length. This is considered to be more secure than stream encryption algorithms like RC4. DES is generally known as not safe enough. Triple DES would however also be a good alternative solution offering a similar level of protection like RC2. The application will also use a randomly generated IV.
Additional information regarding Microsoft Cryptographic Service Providers are on MSDN. If you would like to learn more about Cryptography in general, I suggest the classical works of Bruce Schneier. Another excellent book dedicated for .NET freaks is the C# Data Security Handbook published by Wrox Press. I learned a lot reading this book and I can honestly encourage you to start easily at beginners level with practical cryptography in .NET.
The secure store should certainly have a clearly defined structure holding particular and independent from each other items. Having to deal with .NET, such a structure is offered by the
DataSets are easy to use, their content is easy to persist, and the underlying data source can easily be connected to controls like a
ComboBox which I'm using in this application (Figure 1). Thus the core document structure can be held very simply like displayed in Figure 2.
<SecretData> RC2 encrypted; Base64 encoded </SecretData>
<SecretData> RC2 encrypted; Base64 encoded </SecretData>
Figure 2 The store's basic data structure
Please note, the root "
MyStore" is the
DataSet's name, the "
Secrets" element refers to the single table name, whereas the "
SecretName" and "
SecretData" elements refer to the table's columns. Please also note, the "
SecretData" element value holds the data already encrypted. The encrypted content is additionally Base64 encoded according to the W3C XML text content requirements (character data).
Each item (
SecretData element value) is encrypted based on its own unique 128 bit cryptographically random symmetric key which is created by the MECSP using the initial login password (or pass phrase) and the particular item's name (
SecretName element value). Saving such an XML document to a file would be already safe enough as cryptanalysts would be forced to break as many symmetric keys as secret items exists. However, encrypting the whole wrapper XML structure would offer additional protection level due to the following reasons:
- Each item's name (
SecretName element value) could be chosen without any precautions revealing hidden contents and offering prior knowledge.
- Each item's content (
SecretData element value) would be encrypted twice with a 128 bit symmetric key.
But let me remind you the concerns I have explained in the Introduction. Simply encrypting an XML document would be offering too much prior knowledge for cryptanalysts. Therefore each time the application starts with an empty data store, it proposes randomly generated XML element names scrambling the original XML document like Figure 3 shows. Thus each new document structure generated is different and there is no way to make any assumptions what the element names are like.
<o7fg> RC2 encrypted; Base64 encoded </o7fg>
<o7fg> RC2 encrypted; Base64 encoded </o7fg>
Figure 3 The store's basic data structure
The XML document structure shown in Figure 3 is more appropriate for such an application. For the
DataSet, it does not matter whether the table name is set to "Secrets" or "kwfo7tg1a_" or a random string like that.
The last problem we have to deal with is the fact, that even XML documents with scrambled element names start either with a bite order mark or with the "<" character, which is also an unwanted prior knowledge. This is however the reason the initialization vector (IV) has been introduced which I was talking about earlier.
Sometimes encrypted messages start each time with exactly the same sequence, due to the fact that they have a predefined header, like an E-Mail. The vulnerability of such a data is high as cryptanalysis can act upon a known starting sequence. The initialization vector (IV) is an effective protection against such a vulnerability. The IV is by default set to the same size as the block cipher's length. Using RC2 provided by the MECSP, the block size is set by default to 64 bits (8 byte) which is also the IV length. The IV is generated each write-time by the MECSP providing a cryptographically random value. This value is used to "scramble" the first 8 starting bytes of the document. The IV should not be treated like a second key and can be safely stored along with the secured data store. The IV is useless for anybody not knowing the symmetric key. The IV is used each time the application starts and decrypts the existing data store.
Let me simply emphasize the fact that the whole effort using enhanced symmetric algorithms, long keys and initialization vectors is worthless if you rely on some easy to guess password which is listed in every dictionary used by cryptanalysts. Using this Pocket PC application, you have to memorize just one strong enough password which however has to be absolutely non predictable.
The solution has exactly the same structure I explained in my article Currency Converter for the Pocket PC. Therefore I will keep the explanation short. The solution consists of three particular projects, listed below in their exact build order reflecting the dependencies.
- SecurePocketStore - C# Mobile Smart Device Application project.
- InstallerService - C# Class Library project.
- Setup and Deployment project which packages cabinets and the primary output of the InstallerService project.
The project is built based on the mentioned extended
Crypto class. Fortunately, this
Crypto class can also be used on the desktop. Developing for the Pocket PC however, you have to declare the "
COMPACT_FRAMEWORK" conditional compilation constant (Figure 4), otherwise the P/Invoke will divert the calls to the desktop Windows libraries like Figure 6 displays.
Figure 4 The project's property page
const string CryptDll = "coredll.dll";
const string KernelDll = "coredll.dll";
const string CryptDll = "advapi32.dll";
const string KernelDll = "kernel32.dll";
Figure 5 Referring to the appropriate libraries
I created a wrapper class around the
Crypto class named
EnhancedCrypto which provides encryption/decryption and Base64 encoding/decoding of the Secrets area (which is a multi lined
TextBox control) and also encrypts/decrypts and writes/reads the
DataSet to a file.
Let's take a closer look at the application's structure which is designed to deal with both Portrait and Landscape modes as Figure 6 shows. The methodology of how to do that is explained detailed in my mentioned article.
The application's control centre is the core
ComboBox control along with the multi lined
TextBox control holding the secrets you will type in. All these controls are placed on a
TabPage of a root
ComboBox control displays the list of Item-Names which refer to the standalone pieces of secrets. Every Item (record) is composed by a unique Name and the Secret itself. The plain text size of a particular Secret is limited by default to 32K. I do not believe you will ever be limited because of this size. Every time the
TextBox control loses focus, the area is encrypted/encoded and persisted in the
DataSet. The key is unique for every Item and is generated based on the combined Pass Phrase and Item Name strings. However, you can safely change the Item Name clicking on the "Alter" button. If you accept the changes, a new key is generated immediately for the Secret.
You can navigate through the Items displayed in the
ComboBox either selecting a line directly in the
ComboBox's drop down menu or using the left and right buttons below the
ComboBox. As you can see, you also have the possibility to navigate to the first or to the last Items in the list. Furthermore, you can also sort the Items clicking the Sort
CheckBox control which also may affect which item is considered to be the first or the last.
Figure 6 The application in Landscape mode
The Save & Close button does not just save the encrypted wrapper XML document structure, but also exits the application. As you may be already aware, Pocket PC applications tend to remain in the memory forever. The only way to force them to exit is manually via: "Settings / System / Memory / Running Program List" and thereafter selecting the application and clicking the "Stop" button. Such behavior, of course, is everything but useful for an application like this. Imagine the consequences in case of loss or theft.
To prevent abuse of your secrets, the Secure Store application has to auto-exit prior to the idle Pocket PC device turning off automatically. The "Turn off device if not used" Battery Power property is set by default on every new device to 3 minutes. Thus the application's auto-exit has to be less than 3 minutes. See the bottom area on the right hand side picture in Figure 1 which displays the remaining idle minutes in 30 second steps. If you click the
TextBox, change the
ComboBox selected Item; touching any other control, the timer's counter will be set back each time to the initial 2:30 minutes.
You have been warned. If you switch off your physical Pocket PC device, the Secure Store application will not exit but will remain in a suspended state.
Starting the application the first time, it will create an empty
DataSet with three initial records named "First Item", "Second Item" and "Third Item" (it is perfectly safe to change those Item Names after login). You also need to enter and confirm your password (or better a pass phrase) and confirm or even intentionally change the randomly generated scrambled XML element names (see the left side picture in Figure 1). The pass phrase has to be at least seven characters long but you are advised to choose a longer one. The remaining XML element names (the table columns) are descended from the two entered and confirmed XML element names (download and see the source code for more details).
If the application detects an existing encrypted store, it will ask you the pass phrase to login. Remember, you or anybody else using this application has only five attempts to enter the right password. After the fifth failed attempt, the application will automatically destroy the encrypted file. You however will still have a copy of the file on your desktop or laptop, whatever you have used to synchronize your Pocket PC.
There is also a possibility to change the password, which will cause a loop decrypting all the Items with the old password and encrypting them using the new one. This is also a known weakness of the application as it holds the pass phrase for the time it is running and alive. Exiting the application, the pass phrase and the lastly displayed secret are overwritten with a junk and cleaned up.
In this article, you learned how to start building cryptographically strong applications on the Pocket PC. Download the source and take a look at the classes. You can of course simply start to use the application on your own risk. I'm using it since a few weeks and it seems to work well. I have meanwhile a store of about 4K of cipher text and about 10 items in it. If you have any suggestions or even you see a mistake in my code, do not hesitate to contact me.