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
Windows Mobile Developer Controls

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 

Cryptography

I started targeting the basic crypto services first: Random #'s and working with Providers. Then I moved on to Hashes and Keyed Hashes. Next, was working with Keys and getting access to the raw key data. Finally, Encryption and Signing. The SmartPhone WinForm project in the code has all of these tests. These tests run local on the device and might not be interoperable with the full .NET framework (I will make it interoperable later). The actual Crypto wrapper lives in the bNb.Sec project, which is a CE class library and has no dependencies.

Random

This tested multiple ways of generating random numbers, as well as multiple ways of generating GUIDs.

Providers

This lists the available provider types, providers, and ciphers that are available on a device. On a SmartPhone, the Provider Types are:

  • PROV_RSA_FULL
  • PROV_DSS_DH - not on PPC 2002

Each Provider Type above had 2 Providers:

  • MS Base Crypto Provider [PROV_RSA_FULL]
  • MS Enhanced Crypto Provider - not on PPC 2002 emulator, but on my PPC 2002 device
  • MS Base DSS Diff-Hell [PROV_DSS_DH]
  • MS Enhanced DSS Diff-Hell

These are the Ciphers and (min, max) key length available for the 2 Enhanced Providers above:

  • RC2 (40 128), RC4 (40 128), RC5 (40 128), DES (56 56), 3DES TWO KEY (112 112), 3DES (168 168), SHA-1 (160 160), MD2 (128 128), MD4 (128 128), MD5 (128 128), SSL3 SHAMD5 (288 288), MAC (0 0), RSA_SIGN (384 16384), RSA_KEYX (384 16384), HMAC (0 0) [MS Enhanced Crypto Provider]
  • RC4 (40 128), DES (56 56), 3DES TWO KEY (112 112), 3DES (168 168), SHA-1 (160 160), MD5 (128 128), DSA_SIGN (512 1024), DH_KEYX (512 4096), DH_KEYX (512 4096) [MS Enhanced DSS Diff-Hell]

 

Hash

The most popular are MD5 and SHA1, and they both work on the SmartPhone. MD5 is 16 bytes, SHA1 is 20. MD5 is supposed to be faster, and SHA1 is supposed to be stronger. SHA1 is what you will probably use most of the time in your apps. SSL SHAMD5 is used for SSL (probably what Pocket IE uses), it is a combination of MD5 and SHA1 (thus 36 bytes)

Keyed Hash

The keyed hashes most often used are MacTripleDes and HmacSha1. MacTripleDes combines a TripleDES symmetric key with a MAC hash. The MAC hash ends up being 8 bytes. I could not get it to work on the SmartPhone. It would return a byte [] of 8 bytes, but all of the values were zero. If I used DES instead of TripleDES, then it would get a value. An MS employee was helping me in a newsgroup and posted their working C++ code for doing MacTripleDes. I ported that to eVC++, and still got all 0's, so I think this is a bug in the CryptoApi for SmartPhones (maybe for PocketPC too?). A couple of MS employees have recreated this problem and are looking into it. HmacSha1 is a combination of an HMAC and a SHA1 hash. This worked on the SmartPhone with no problems. Originally coded this with using the CALG_HMAC algId. From a newsgroup posting, I ended up having to change this to doing multiple SHA1 hashes after doing some key manipulation. With that change it became more compatible with the full framework. I also tested the CryptHashSessionKey here. I did by getting access to the raw session key data (explained below), manually hashing that key, and making sure those bytes matched the hash obtained by calling CryptHashSessionKey.

Keys

I started out working with symmetric keys (DES, TripleDES, and RC2). Made sure CryptGenKey created random keys each time, and CryptDeriveKey would create the same key each time. Also, attempted to import and export raw session keys. Unluckily, the CryptoApi makes this tedious to accomplish. The rule of thumb is that session keys should never be transferred in the clear, so the CryptoApi forces you to encrypt the session key with an asymmetric key to get the random bytes. Of course, there is a convoluted workaround that lets you get the raw session keys with what is called an exponent-of-one private key. The concept is x * 1 = x, where 1 is the exponent-of-one key. So when you export or import the session key, no bytes are actually changing. When you finally extract a session key in the clear, it will come out being something like 142 bytes. This is odd because session keys are mostly in the range from 8 to 24 bytes. The 142 bytes are a SimpleBlob structure that MS has defined. Its basically header info, the actual key, and then random bytes. Asymmetric keys are easier to import and export. You can just ask for the PublicKeyBlob or PrivateKeyBlob and get access to their plaintext bytes, also in MS defined wrappers.

For symmetric keys, DES is no longer considered secure. RC4 is supposed to be faster than RC2, and RC2 is supposed to be stronger. TripleDES replaces DES and is supposed to be stronger than RC2 and RC4. For asymmetric keys, the PROV_RSA_FULL provides us with RSA which can be used for encrypting and signing. NOTE you should not encrypt and sign with the same key pairs. The PROV_DSS_DH provider types provide DSA. DSA can only be used for signing.

Encryption

The unportable way is to use CryptProtectData with CryptUnprotectData. I'm not exactly sure how CryptProtectData is encrypting the data, but I believe it is tied to a machine. So that if you encrypt with ProtectData on deviceX, then you cannot use CryptUnprotectData to decrypt on deviceY. This seems useful as a means to store keys that need to be reused.

The other methods are CryptEncrypt and CryptDecrypt to be used with the standard symmetric and asymmetric algorithms, which will be portable across devices. Symmetric algorithms are much faster than asymmetric, so the rule of thumb is to use symmetric algorithms to encrypt data with a session key, and then encrypt session keys with pub / priv keys to pass the session key over the wire. For symmetric encryption, you encrypt and decrypt with the same key. For asymmetric encryption you encrypt with somebody else's public key, and they decrypt with their private key.

Signing

This is possible with pub / priv keys. To sign, you use your private key (typically on a hash value), and then that signature can be verified with your public key on another device. To sign with the CryptoApi you use CryptSignHash, and verify with CryptVerifySignature. I made sure that these calls worked and that a signature would not verify if a byte was changed.

Certificates

Most of what we have looked at until now is CryptoApi 1.0, which is basically complete on a SmartPhone. CryptoApi 2.0 introduces more functionality, mainly for dealing with Certificates, with about 1/2 of it existing for SmartPhones. I did not wrap these interfaces as well, and will use the managed System.Security.Cryptography.X509Certificates.X509Certificate class, which does exist in the .NETcf.

 

Previous Page  Next Page