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 

.NETcf does not have the namespace System.Security.Cryptography. Yet we really need it as the world becomes more wireless, and we don't want our data available in the clear for wireless sniffers or network operators, especially with certain wireless security mechanisms being in question (i.e. WEP). Luckily, both the SmartPhone and PocketPC devices come with the CryptoApi. The CryptoApi is an unmanaged API used to call unmanaged cryptographic implementations that exist on the devices as well. This can be done through pInvokes. In this article I will wrap the entire CryptoApi (version 1). As needed, I will then provide higher level wrappers that loosely match the .NET namespace. Finally, I will test for cross platform compatibility between my implementation for CE and the full framework on a desktop.

I looked at the current .NETcf crypto implementations before starting this. The best ones were the Pocket PC Signature Application Sample which has been around for a while, and lately the implementation from a Cryptography chapter in the Microsoft .NET Compact Framework Kick Start (I recommend this book). PPC Signature provides an MD5 hash and uses RC2 symmetric keys for exchanging data. The ManagedCryptoAPI from the Kick Start book provides an MD5 hash, DES and RC4 symmetric encryption for exchanging data, and RSA for asymmetric encryption for exchanging keys. The MD5 hash is compatible with the full framework, but the other ciphers are not out of the box. NOTE I saw a PDC posting today that Whidbey will provide .NETcf with built-in Cryptography support!

SmartPhone

I developed this with the SmartPhone 2003 emulator. 2003 is important, because SP 2002 does not support .NETcf. Also, 2003 has .NETcf with SP1 in ROM. Pocket PC 2003 and Pocket PC Phone Edition 2003 do not have SP1 in ROM, so you could get unexpected behavior. In general though, this code should work on any device that can run the .NETcf and has the CryptoApi available. NOTE I am using the enhanced version of the crypto providers; base providers do not provide implementations for all of the algorithms below

CryptoApi Functions

The 1st order of business was creating the wrapper around the exported functions of the CryptoApi (Crypto.cs) and defining the constants, error codes (Const.cs) and structures (Structs.cs) from wincrypt.h in managed code. Then, I began testing them to make sure they all worked (the ones in RED did not work on the SmartPhone emulator):

  • CeGenRandom - for creating random bytes. use this call when the CryptoApi is not available, else use CryptGenRandom
  • CPAcquireContext - use CryptAcquireContext instead
  • CryptAcquireContext - to get a handle for a CryptoServiceProvider. needed for most calls
  • CryptContextAddRef - not needed, just create a new Provider each time with CryptAcquireContext
  • CryptCreateHash - for getting a handle to a Hash object
  • CryptDecrypt - decrypting data (symmetric or asymmetric)
  • CryptDeriveKey - pass in a hash of a password / phrase, and it derives the same Key each time
  • CryptDestroyHash - releasing the Hash object handle obtained from CryptCreateHash
  • CryptDestroyKey - releasing the Key object handle obtained from CryptCreateKey, CryptGenKey, CryptImport/ExportKey
  • CryptDuplicateHash - not needed, just create a new Hash each time with CryptCreateHash
  • CryptDuplicateKey - not needed, just create a new Key with one of the methods available
  • CryptEncrypt - encrypting data (symmetric or asymmetric)
  • CryptEnumProviders - lists the Providers available on a device (e.g. MS_ENHANCED_PROV)
  • CryptEnumProviderTypes - not needed, same info can be obtained from CryptEnumProviders
  • CryptExportKey - getting access to the raw Keys in byte [] form
  • CryptGenKey - creating a random Key, mainly used for session (symmetric) keys
  • CryptGenRandom - generating random bytes. stronger than managed System.Random class
  • CryptGetDefaultProvider - not needed, can be obtained with CryptAcquireContext instead
  • CryptGetHashParam - for obtaining the actual Hash value or Hash size from a Hash object
  • CryptGetKeyParam - used to retrieve IV, KeySize, BlockSize, Salt, etc... from a Key
  • CryptGetProvParam - retrieves info about a Provider
  • CryptGetUserKey - gets a users public / private key pair (asymmetric) for signing or exchanging
  • CryptHashData - to tell a Hash object to actually compute the Hash value
  • CryptHashSessionKey - gets a Hash of a session key
  • CryptImportKey - for importing a key that might have been saved to disk or from a WS call
  • CryptProtectData - for locally encrypting data that only the same device can decrypt
  • CryptReleaseContext - releasing the Provider handle obtained from CryptAcquireContext
  • CryptSetHashParam - for setting values on a Hash object
  • CryptSetKeyParam - for setting values on a Key object
  • CryptSetProvider - for setting values on a Provider object
  • CryptSetProviderEx - not needed, use CryptSetProvider instead
  • CryptSetProvParam - for setting parameter values on a Provider object
  • CryptSignHash - to digitally sign a hash value
  • CryptUnprotectData - for decrypting data encrypted with CryptProtectData
  • CryptVerifySignature - to verify a signature of a hash

As you can see above, all of the calls either work, or are not necessary because their functionality can be obtained from a different call. The pass above was just to see if the calls worked or not. I then moved on to see what interesting things could be accomplished with these calls; because this was my first time really working with the CryptoApi.

Next Page