Skip to main content

Articles

Featured Products

Windows Mobile Developer Controls
Windows Mobile Developer Controls
Stay in touch using the DEVBUSS RSS feeds.
 

News

Windows Mobile Developer Controls
Sapphire Soltuions

SmartPhone (SP) and CryptoApi with CompactFramework (.NETcf)

Written by casey chesnut  [author's bio]  [read 36135 times]
Edited by Derek

Download the code

Page 1  Page 2  Page 3  Page 4 

Key Management

The Crypto Api treats symmetric (session) and asymmetric (pub/priv key pair) differently. Session keys only live in memory, so if you need to reuse one you have to handle that yourself. One option might be using CryptProtectData and CryptUnprotectData to save it to disk. For key pairs, each named container stores 2 key pairs, 1 for exchanging (e.g. encrypting) and 1 for signing. For PROV_RSA_FULL, you get 2 RSA key pairs because it can be used to encrypt and sign. For PROV_DSS_DH, you get DSA for signing and Diffie-Hellman keys for key exchange. Also, these key pairs are stored in the registry, so when you are importing and exporting keys, you have to be careful not to step on your own keys. To handle this, all session keys use their own named container, and the key pairs for that container will end up being 'exponent-of-one' keys so that the session keys can be exported in the clear. Therefore, those pub/priv keys should never be used for exchanging or signing. For RSA and DSA, my implementation uses the users key by default. I do this for speed, because it takes some time to generate a key each time. There is a static property that can be set to make it gen a key each time. Also, when importing keys, it uses a different container so as not to destroy the users key. Sometimes I get an error BAD_KEY_STATE when using the user key (mostly with PROV_DSS_DH provider). To get around this, I have a ResetKeyState method in the Key class. This would destroy your key pairs and create new ones, so you might want to export them to Xml and save them locally using ProtectData and then import them later on. To complicate things even more, if you are sending a message that needs to be signed and encrypted, then you should use different key pairs. So for RSA (which can do both), encryption uses the EXCHANGE key pair, while signing uses SIGNATURE key pair. Better yet, use RSA for encryption and DSA for signing.

Performance

SmartPhones have processors as low as 132 megahertz, so we have to think about speed. When starting out to code this, I was either going to pInvoke the CryptoApi, or port the Mono implementation that is all managed. My assumption was that the cost to pInvoke the CryptoApi was going to be less than doing the ciphers in all managed code. Also, the different algorithms will perform differently. MD5 is supposed to be faster than SHA1. RC4 is supposed to be much faster than RC2 (although RC4 doesnt exist on the full framework). Symmetric algorithms are much faster than asymmetric algorithms, so the rule of thumb is to encrypt the data with symmetric, then encrypt the symmetric key (which is small) with an asymmetric algorithm. Next, dont sign big chunks of data; instead take a hash of the data and just sign the hash. Finally, if you are encrypting a large chunk of data with a symmetric key, then you will want to display progress to the user. My wrapper does not currently allow for the data to be encrypted in chunks, but it could be extended to do so because the CryptoApi does. If performance is a real big issue, an eVC wrapper could be written which exposes methods consisting of multiple CryptoApi calls to reduce the number of pInvokes required for each cipher.

Conclusion

So we now have interoperability between the desktop and the device with almost all of the System.Security.Cryptography namespace. MACTripleDES seems to be broken on CE, so use HMACSHA1 instead. PasswordDeriveBytes is partially compatible with RC2 / SHA1, and DES / MD5 is close (except for salting); although this might not be compatible on other platforms outside of the CryptoApi. Finally, the CryptoApi providers on the SmartPhone offer no way to do the hashes (SHA 256/384/512) nor Rijndael (symmetric) encryption. 

Books

I'm a crypto wannabe, so I referred to these books during writing this

  • Cryptography for Visual Basic, Bondi
  • Cryptography (RSA Security's Official Guide), Burnett and Paine
  • Programming .NET Security, Freeman and Jones
  • Writing Secure Code, Howard and LeBlanc
  • .NET Security, Bock and Stromquist ...
  • Practical Cryptography, Schneier and Ferguson
  • Java Cryptography, Jonathon Knudsen
  • and the CryptoApi documentation

Source

  • bNb.Sec (CE class lib) wrapper over CryptoApi, with helper classes
  • System.Security.Cryptography (CE class lib) wraps bNb.Sec for full framework interoperability
  • spCrypt (SmartPhone WinForm) client unit testing
  • /wsCyrpto (ASP.NET Web Service) web service test harness for compatibility with desktop

Future

I wrote this with the intention of asking for volunteers to help move it into OpenNetCF.org workgroup to continue work on it. With the MS announcement that they will be adding Cryptography to .NETcf, I'm less interested, but could be persuaded otherwise? Also, I have a follow up article (why I wrote this library in the 1st place) that will be released within a couple of weeks ...

Previous Page