logo

Compact Framework : Encrypted WebService Communications with CryptoAPI
By Peter A. Bromberg, Ph.D.
Printer - Friendly Version

Peter Bromberg

Since its version 1.0 launch about a year ago at Microsoft Mobile DevCon (MDC) 2003, the .NET Compact Framework has attracted more than 150,000 developers and has become the fourth most active .NET newsgroup on the Internet. Version 1.0 and two subsequent service packs have been factory burned into all new Pocket PC and Smartphone device ROMs.



I've been playing with CF ever since the first emulator was made available, (and first used the Mobile Internet Toolkit in 2001) and now I'm seeing some demand for actual production applications. Most of these revolve around the concept of hand-held partially-connected survey, assessment, transaction recording, and other information-accumulating applications that need to be able to connect later and "synchronize" or upload their data to a server, usually a database.

SQL Server CE, available for the Compact Framework, does support encryption of the database. However, I suspect there are a significant number of Compact Framework applications for which either SQL Server CE could pose unwanted client license expenses or for which it is simply "overkill" because all you really need to do is send data over the wire securely, encrypted with a suitable passphrase known only to the client and the server.

The .NET Compact Framework 2.0, to be released with Visual Studio 2005 (or whatever its real name ends up being) offers lots of enhancements, but managed cryptography classes mirroring the regular .NET Framework's managed cryptography - related classes still don't appear to be in the picture. That means if we want to enjoy secure communication from our device to a server in a wireless environment, we need to access the CryptoAPI provided in Core.dll on the device through PInvoke. And, wireless is fast becoming as ubiquitious as Wendy's Hamburgers and Oreo cookies.

The CryptoAPI on the Compact Framework is not 100% identical to that in the Windows operating system, but enough of it is the same so that we have a choice of some algorithms that will match.

The wrapper class I've engineered here that is included in both the WebService and the Compact Framework demo Windows Application in the download below contains most of the constants for the CryptoAPI, but you are likely to find that some of them do not work on the Compact Framework. There are several reference implementations of PInvoke for the CryptoAPI on the net, one of which goes much farther, if you are interested. Here are some useful links:

"Devbuzz: Smartphone and CryptoAPI..."
"Definitive Guide to the .NET Compact Framework"
"Pocket PC Signature Application"

Mine borrows from all of the above as well as implementing my own enhancements and "fixes", particularly in the area of CryptAcquireContext, where treatment of unsigned integers appears to be not exactly the same on the two platforms.

Because all my methods, including one I've included to create an MD5 Hash, are static, making a webservice encryption or decryption call for a string is as simple as this:

CryptoService.Service1 s = new CryptoService.Service1();
string res= s.ReceiveAndReturnEncryptedString(this.txtEncrypt.Text);

The above will return a Base64 encoded encrypted version of the string that was passed to it. The local method on the Compact Framework looks like so:

string result=CryptoAPI.EncryptString(txtEncrypt.Text,txtHashValue.Text);

I've also provided overloads to my EncryptString and DecryptString methods that use a built-in constant GUID string for the passphrase, but in practice I doubt one would really want to use these as it is so easy to reverse - engineer out the GUID. The way I have this set up now, it's using the DES algorithm for encryption, which is pretty fast.

Examples of the UI follow, first one before sending to the webservice, and the second showing the encrypted result as well as having created a hash on the password:

To set this solution up, just unzip the file into any folder and make the CryptoAPICFService folder an IIS Application. Then, in the proxy code for the WebService reference "Reference.cs" (click the "Show All File" button at the top of Solution Explorer to see this), you will need to change the URL of the service in the proxy class to match the actual IP address of the machine you are hosting it on. Mine currently looks like:

public Service1(){
this.Url = "http://192.168.0.100/CryptoAPICFService/Service1.asmx";
}

-- So, unless the Class C IP address on your machine is the same as the above, your webservice calls will fail until you change it and rebuild. I do this because I ahve found that "localhost" doesn't always work with the Emulators and also because in many cases (such as in production, maybe!) the webservice won't even be on the same machine anyway.

I have also provided methods in my CryptoAPI wrapper class that will encrypt / decrypt byte arrays without any Base64 encoding. This would be suitable for encrypting and sending files over the wire. If you were so inclined, you could easily combine this approach with my Compressed DataSet methods to send Compressed, encrypted DataSets back and forth over the wire.

Download the Source Code that accompanies this article

 

 

Peter Bromberg is a C# MVP, MCP, and .NET consultant who has worked in the banking and financial industry for 20 years. He has architected and developed web - based corporate distributed application solutions since 1995, and focuses exclusively on the .NET Platform. Pete's samples at GotDotNet.com have been downloaded over 41,000 times. You can read Peter's UnBlog Here.  --><--NOTE: Post QUESTIONS on FORUMS!
Do you have a question or comment about this article? Have a programming problem you need to solve? Post it at eggheadcafe.com forums and receive immediate email notification of responses.