在.net flamework完全版中對(duì)system.security.cryptography名字空間下的加密類(lèi)支持得很好。但在精簡(jiǎn)版中卻沒(méi)有提供這個(gè)名字空間中的相應(yīng)的類(lèi)。在用.net寫(xiě)pocket pc程序的時(shí)候用的加密算法的時(shí)候確實(shí)比較麻煩。一般有兩種方法來(lái)解決這個(gè)問(wèn)題。opennetcf(www.openetcf.org)提供了system.security.cryptography名字空間下的各個(gè)類(lèi)的模擬,但它的提供缺乏靈活性:比如在對(duì)稱(chēng)加密的時(shí)候,用戶(hù)無(wú)法設(shè)置padding, ciphermode等屬性。而且它的提供方式和完全版的.net下的類(lèi)的接口不一致,這樣給用戶(hù)造成困惑。另一種方法就是自己動(dòng)手對(duì)cryptoapi進(jìn)行自己封裝。
最近出于工作需要對(duì)md5cryptoserviceprovider進(jìn)行了實(shí)現(xiàn),這個(gè)類(lèi)的接口和完整版下面的接口完全一致。
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