|
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
|