65.9K
CodeProject 正在变化。 阅读更多。
Home

实现 MD5CryptoServiceProvider,就像在完整框架中一样

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.23/5 (4投票s)

2005年3月12日

CPOL
viewsIcon

47279

downloadIcon

418

.NET CF 的 MD5CryptoServiceProvider。

Sample Image - MD5CryptoServiceProvider.jpg

引言

完整的 .NET Framework 包含对加密功能的丰富支持,例如使用各种算法计算哈希和加密数据。

大多数 Windows CE 设备和所有 Pocket PC 设备都包含 CryptoAPI 的实现,这是一个本机代码库,执行各种加密功能。 其架构允许开发人员添加新的算法包,从而扩展加密功能,同时保留用于访问新算法的熟悉 API。

OpenNetCF 提供了一个非常庞大且集成的库,其中包含“OpenNETCF.Security.Cryptography”命名空间,用于替换完整的 .NET Framework 中的“System.Security.Cryptography”命名空间。 但它与完整的 .NET Framework 接口不相同,这会让用户感到困惑。 本主题提供了一个示例,以实现 MD5 作为哈希加密功能。 此示例通过 P/Invoke CryptoAPI 实现它。

实现

演示代码列表

private void Form1_Load(object sender, System.EventArgs e)
{
    HashAlgorithm x_hash_alg = HashAlgorithm.Create("MD5");
    foreach(ListViewItem lvi in this.listView1.Items)
    {
      byte[] x_buf=System.Text.Encoding.ASCII.GetBytes(lvi.Text);
      byte[] x_hash_code = x_hash_alg.ComputeHash(x_buf);
      string s=ArrayToString(x_hash_code);
      lvi.SubItems.Add(s);
    }
    this.listView1.Refresh();
}
private string ArrayToString(byte[] buf)
{
    string str="";
    for(int i=0;i<buf.Length;i++)
    {
      string tmp=buf[i].ToString("x");
      if(tmp.Length>1)
      {
        str+=tmp;
      }
      else
      {
        str+="0"+tmp;
      }
    }
    return str;
}

实现“System.Security.Cryptography.MD5CryptoServiceProvider”类

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));
    }
 }

P/Invoke 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;
  }
 }

参考文献

© . All rights reserved.