在.net flamework完全版中对system.security.cryptography名字空间下的加密类支持得很好。但在精简版中却没有提供这个名字空间中的相应的类。在用.net写pocket pc程序的时候用的加密算法的时候确实比较麻烦。一般有两种方法来解决这个问题。opennetcf(www.openetcf.org)提供了system.security.cryptography名字空间下的各个类的模拟,但它的提供缺乏灵活性:比如在对称加密的时候,用户无法设置padding, ciphermode等属性。而且它的提供方式和完全版的.net下的类的接口不一致,这样给用户造成困惑。另一种方法就是自己动手对cryptoapi进行自己封装。
最近出于工作需要对md5cryptoserviceprovider进行了实现,这个类的接口和完整版下面的接口完全一致。
implementation of the "system.security.cryptography.md5cryptoserviceprovider" class. 
 
public sealed class md5cryptoserviceprovider : md5 
 {
 public md5cryptoserviceprovider() 
 {
 initialize();
 m_disposed = false;
 }
 public override void initialize() 
 {
 if (m_disposed)
 throw new objectdisposedexception(this.gettype().fullname);
 if (m_hash != intptr.zero) 
 {
 crypto.cryptdestroyhash(m_hash);
 }
 m_prov = crypto.acquirecontext(provtype.rsa_full);
 bool retval=crypto.cryptcreatehash(m_prov, (uint)calghash.md5, intptr.zero, 0, out m_hash);
 
 }
 protected override void hashcore(byte[] array, int ibstart, int cbsize) 
 {
 if (m_disposed)
 throw new objectdisposedexception(this.gettype().fullname);
 byte[] copy = (byte[]) array.clone();
 //array.copy(array, ibstart, copy, 0, cbsize);
 bool retval=false;
 retval=crypto.crypthashdata(m_hash, copy, copy.length, 0);
 }
 protected override byte[] hashfinal() 
 {
 if (m_disposed)
 throw new objectdisposedexception(this.gettype().fullname);
 byte [] data = new byte[0];
 uint datalen = 0;
 uint flags = 0;
 //size
 bool retval = crypto.cryptgethashparam(m_hash, (uint) hashparam.hashval, data, ref datalen, flags);
 if(234 == marshal.getlastwin32error())//more_data = 234,
 {
 //data
 data = new byte[datalen];
 retval = crypto.cryptgethashparam(m_hash, (uint) hashparam.hashval, data, ref datalen, flags);
 }
 return data;
 }
 protected override void dispose(bool disposing) 
 {
 if (!m_disposed) 
 {
 if (m_hash != intptr.zero) 
 {
 bool retval=crypto.cryptdestroyhash(m_hash);
 m_hash = intptr.zero;
 }
 if(m_prov!=intptr.zero)
 {
 crypto.cryptreleasecontext(m_prov, 0);
 m_prov=intptr.zero;
 }
 try 
 {
 gc.suppressfinalize(this);
 } 
 catch {}
 m_disposed = true;
 }
 }
 ~md5cryptoserviceprovider() 
 {
 clear();
 }
 private intptr m_hash=intptr.zero;
 private bool m_disposed;
 private intptr m_prov=intptr.zero;
 }
 
public abstract class md5 : hashalgorithm
 {
 // constructor.
 protected md5()
 {
 hashsizevalue = 128;
 }
 
 // create a new instance of the "md5" class.
 public new static md5 create()
 {
 return (md5)(cryptoconfig.createfromname
 (cryptoconfig.md5default, null));
 }
 public new static md5 create(string algname)
 {
 return (md5)(cryptoconfig.createfromname(algname, null));
 }
 
 }; // class md5
 
p/invoke the cryotoapi
public class crypto
 {
 [dllimport("coredll.dll", entrypoint="cryptacquirecontext")] 
 public static extern bool cryptacquirecontext(out intptr hprov, string pszcontainer, string pszprovider, uint dwprovtype, uint dwflags);
 
 [dllimport("coredll.dll", entrypoint="cryptcreatehash")] 
 public static extern bool cryptcreatehash(intptr hprov, uint algid, intptr hkey, uint dwflags, out intptr phhash); 
 
 [dllimport("coredll.dll", entrypoint="cryptdestroyhash")] 
 public static extern bool cryptdestroyhash(intptr hhash);
 
 [dllimport("coredll.dll", entrypoint="crypthashdata")] 
 public static extern bool crypthashdata(intptr hhash, byte[] pbdata, int dwdatalen, uint dwflags); 
 
 [dllimport("coredll.dll", entrypoint="cryptgethashparam", setlasterror=true)] 
 public static extern bool cryptgethashparam(intptr hhash, uint dwparam, byte[] pbdata, ref uint pdwdatalen, uint dwflags); 
 
 [dllimport("coredll.dll", entrypoint="cryptreleasecontext")] 
 public static extern bool cryptreleasecontext(intptr hprov, uint dwflags); 
 
 public static intptr acquirecontext()
 {
 return acquirecontext("md5container", provname.ms_enhanced_prov, provtype.rsa_full, contextflag.none);
 }
 
 public static intptr acquirecontext(string container)
 {
 return acquirecontext(container, provname.ms_enhanced_prov, provtype.rsa_full, contextflag.none);
 }
 
 public static intptr acquirecontext(provtype provtype)
 {
 return acquirecontext(null, null, provtype, contextflag.none);
 }
 
 public static intptr acquirecontext(string provname, provtype provtype)
 {
 return acquirecontext(null, provname, provtype, contextflag.none);
 }
 
 public static intptr acquirecontext(string provname, provtype provtype, contextflag conflag)
 {
 return acquirecontext(null, provname, provtype, conflag);
 }
 
 public static intptr acquirecontext(string conname, string provname, provtype provtype)
 {
 return acquirecontext(conname, provname, provtype, contextflag.none);
 }
 
 public static intptr acquirecontext(string conname, string provname, provtype provtype, contextflag conflag)
 {
 intptr hprov;
 bool retval = crypto.cryptacquirecontext(out hprov, conname, provname, (uint) provtype, (uint) conflag);
 if(!retval) //try creating a new key container
 {
 retval = crypto.cryptacquirecontext(out hprov, conname, provname, (uint) provtype, (uint) contextflag.newkeyset);
 }
 if(hprov == intptr.zero)
 throw new exception("system.security.cryptography");
 return hprov;
 }
 }
代码下载在codeproject上有:http://www.codeproject.com/useritems/md5cryptoserviceprovider.asp
reference:
dot net compact framework kick start 2003
www.opennetcf.org
http://www.koders.com/csharp/fidc21861b5f1b717ec1fdec006dbd0b8226b92d878.aspx