|
Development | .NET Compact Framework
SmartPhone (SP) and CryptoApi with CompactFramework (.NETcf)
Written by casey chesnut
[author's bio]
[read 35859 times]
Edited by Derek
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
Back to .NET Compact Framework | [Article Index]
|