热门文章
阿标在线 动力3.62HTML生成3.62网站文件说明
动力3.62整合动网7.0 SP2插
MDAC2.8 下载!
动力3.62版 防止垃圾留言
动力3.6全方位改动方法
让3.62不同频道实现不同风
把3.62首页登陆为横向代码
动易3.6首页随机FLASH修改
362首页和文章频道页图文幻
个性化修改3.6宝典
3.62轻易实现网摘功能
如何正确统计中文字数?
弹出JAVASCRIPT语法错误对
后台使“网站顶部LOGO地址
最新图片文章横向移动的修
html 生成艺术字
3.6 Sp2 Logo和Banner及广
日期值的计算
汉字转拼音
首页“图片更新”图片滚动
简体中文转换为繁体中文的
如何在css中定义链接的下划
.net Compact Flamework中MD5CryptoServiceProvider的实现
[ 录入:阿标 | 点击数: | 更新时间:2005-3-18 12:43:00]
在.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