采用系统提供的加密图形服务计算 MD5 哈希

计算内存块的哈希值一般采用 MD5,SHA 两种加密算法,现在最常用的仍然是 MD5,因为 MD5 有着速度快,冲突少的优势,下面就来说一些如何使用系统加密图形服务进行 MD5 计算,先参考封装的类:

#pragma once

#include 
<wincrypt.h> 

namespace CryptGraphics
{
    
struct CryptContext
    {
        CryptContext(LPCTSTR szContainer 
= NULL, LPCTSTR szProvider = NULL, DWORD dwProvType = PROV_RSA_FULL)
        { 
            hProvider 
= NULL; Acquire(szContainer, szProvider, dwProvType);
        }
        
        
~CryptContext() { Release(); }

        BOOL Acquire(LPCTSTR szContainer 
= NULL, LPCTSTR szProvider = NULL, DWORD dwProvType = PROV_RSA_FULL)
        {
            
// 如果 szContainer 指定的容器存在,那么直接返回,否则新建一个。
            CHK_EXP_RET(CryptAcquireContext(&hProvider, szContainer, szProvider, dwProvType, 0) , TRUE ); 
            
return CryptAcquireContext(&hProvider, szContainer, szProvider, dwProvType, CRYPT_NEWKEYSET);
        }

        BOOL Release() 
        {
            BOOL bReturn 
= CryptReleaseContext(hProvider, NULL);
            hProvider 
= NULL; return bReturn; 
        }

        HCRYPTPROV hProvider;
    };

    
class CHashMD5 : public CryptContext
    {
    
public:
        CHashMD5( ) : hChiper( NULL ) {    Initialize(); }
        
~CHashMD5( ) { Terminate( ); }

    
public:
        BOOL Chiper( LPBYTE lpData , DWORD dwSize ) { 
return CryptHashData(hChiper, lpData, dwSize, 0); }

        BOOL Result( DWORD
& dwSize, LPBYTE lpData = NULL )
        {
            DWORD dwParam 
= lpData == NULL ? HP_HASHSIZE : HP_HASHVAL ;
            
return CryptGetHashParam(hChiper, dwParam, lpData, &dwSize, 0);
        }

    
public:
        BOOL Create( ) { 
return CryptCreateHash(hProvider, CALG_MD5, NULL, 0&hChiper); }
        BOOL Destroy( ) { 
return CryptDestroyHash(hChiper); }

    
protected:
        BOOL Initialize() { 
return Create(); }
        BOOL Terminate() { 
return Destroy(); }

    
protected:
        HCRYPTHASH hChiper;
    };

}

有了上面的封装类,计算 MD5 就简单多了,参考如下代码:

    CryptGraphics::CHashMD5 xChiper;
    xChiper.Chiper((LPBYTE)lpData, dwData);

    DWORD dwResult[
4= { 0 };
    DWORD dwSize 
= sizeof(dwResult);
    xChiper.Result(dwSize, (LPBYTE)dwResult);

另外如果是需要对文件计算 MD5 HASH ,其实可以不必自己实现加载文件到内存进行 MD5 运算的复制代码,使用 MSI 中提供的函数就可以简单实现,如下所示:

    MSIFILEHASHINFO xHashInfo = { sizeof( MSIFILEHASHINFO ) };
    UINT nCaller 
= MsiGetFileHash( szPath , 0 , & xHashInfo );

判断返回值即可知道 MD5 计算是否成功,如果成功,计算的结果就放在 xHashInfo 的 dwData 数组中,

虽然 MD5 现在已经可以算是被破解了(山东大学王晓云女博士提供了可以在很短时间内伪造MD5签名的算法),但是仅限于使用 MD5 的结果来对机密信息进行加密不再安全了,如果是一般性应用还是没有任何问题的,当然如果对 MD5 不放心的话可以使用 SHA , 当然要 SHA-256 及其以上的才行;

posted @ 2009-03-16 09:23  王志科  阅读(499)  评论(0编辑  收藏  举报