CryptoAPI函数测试实例代码(一)

2014-11-23 23:30:16 · 作者: · 浏览: 24
#include "stdafx.h"  
#include "h\util.h"  
namespace UI { namespace Util  
{  
  
#ifdef UTIL_CRYPT  
  
#include "Wincrypt.h"  
#pragma comment(lib, "Crypt32.lib")  
//  
//  函数: void MD5_Digest( BYTE* bOrign, int nOriLen, CBuffer *pDigestBuf )  
//    
//  目的: 对给定的字节流做摘要  
//  
//  参数:  
//      bOrign  
//          [in]:   要做摘要的字节流  
//      nOriLen  
//          [in]:   szOrign字节流的长度  
//      pDigestBuf  
//          [out]:  返回摘要值,33位的长度(包括NULL)  
//  
//  返回: 成功返回TRUE,失败返回FALSE;  
//  
//  备注: 支持ASCII和UNICODE  
//        
BOOL MD5_Digest( BYTE* bOrign, int nOriLen, CBuffer *pDigestBuf )  
{  
    HCRYPTPROV      hCryptProv  = NULL;  
    HCRYPTHASH      hHash       = NULL;  
    BOOL            bRet        = FALSE;  
    do  
    {  
        bRet = ::CryptAcquireContext( &hCryptProv, 0, NULL, PROV_RSA_FULL, 0 );  
        if( FALSE == bRet )  
            break;  
  
        bRet = ::CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash );  
        if( FALSE == bRet )  
            break;  
  
        // 做摘要  
        ::CryptHashData( hHash, bOrign, nOriLen, 0 );  
  
        DWORD dwHashLen = 0;  
        DWORD dwDataLen = sizeof(DWORD);  
        CBufferT buf;  
  
        // 先获取摘要的长度,再分配内存获取摘要值  
        if( FALSE == ::CryptGetHashParam( hHash, HP_HASHSIZE, (BYTE*)&dwHashLen, &dwDataLen, 0 ) )  
            break;  
  
        buf.malloc( dwHashLen );  
        dwDataLen = dwHashLen;  
  
        if( FALSE == ::CryptGetHashParam( hHash, HP_HASHVAL, buf, &dwDataLen, 0 ) )  
            break;  
      
        B2HS( (BYTE*)buf, buf.GetBufSize(), *pDigestBuf );  
        bRet = TRUE;  
    }  
    while(false);  
  
    if( hHash )  
        ::CryptDestroyHash( hHash );  
    if( hCryptProv )  
        ::CryptReleaseContext( hCryptProv, 0 );  
  
    return bRet;  
}  
  
//  
//  函数: void MD5_String_Digest( TCHAR* str, CBuffer* pDigestBuf )  
//    
//  目的: 对给定的字符串做摘要  
//  
//  参数:  
//      str  
//          [in]:   要做摘要的字符串,兼容ASCII和UNICODE,对于UNICODE,  
//                  是将其转换为ASCII。因为做摘要它只是针对BYTE而言  
//      pDigestBuf  
//          [out]:  返回摘要值,33位的长度(包括NULL)  
//  
//  返回: 成功返回TRUE,失败返回FALSE;  
//  
//  备注: 内部调用MD5_Digest  
//        
BOOL MD5_String_Digest( TCHAR* str, CBuffer* pDigestBuf )  
{  
#ifdef _UNICODE  
    CBufferT
buf; U2A( str, buf ); return MD5_Digest( (BYTE*)(char*)buf, wcslen(str), pDigestBuf ); #else return MD5_Digest( (BYTE*)str, strlen( str ), pDigestBuf ); #endif } // // 函数: BOOL MD5_File_Digest( TCHAR* szPath, CBuffer* pDigestBuf ) // // 目的: 对一个文件做摘要 // // 参数: // szPath // [in]: 要做摘要的文件路径 // pDigestBuf // [out]: 返回摘要内容 // // 返回: 成功返回TRUE,失败返回FALSE; // BOOL MD5_File_Digest( TCHAR* szPath, CBuffer* pDigestBuf ) { CBufferT fileBuf; if( FALSE == GetFileBuffer( szPath, fileBuf ) ) return FALSE; return MD5_Digest( (BYTE*)(char*) fileBuf, fileBuf.GetBufSize(), pDigestBuf ); } // // 函数: void Encrypt( BYTE* bOrign, int nOriLen, TCHAR* szPassword, CBuffer* pEncryptBuf ) // // 目的: 对字节流使用指定的密码进行加密 // // 参数: // bOrign // [in]: 要加密的字节流 // nOriLen // [in]: 要加密的字节流的长度 // szPassword // [in]: 加密所用的密码 // pEncryptBuf // [out]: 返回加密后的内容 // // 备注: 该函数尚未完成 // void Encrypt( BYTE* bOrign, int nOriLen, TCHAR* szPassword, CBuffer* pEncryptBuf ) { HCRYPTPROV hCryptProv = NULL; HCRYPTHASH hHash = NULL; HCRYPTKEY hKey = NULL; BOOL bRet = FALSE; do { bRet = ::CryptAcquireContext( &hCryptProv, 0, NULL, PROV_RSA_FULL, 0 ); if( FALSE == bRet ) break; bRet = ::CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash ); if( FALSE == bRet ) break; // 对密码做一次HASH,用于产生会话密钥 #ifdef _UNICODE CBufferT pswdBuf; U2A( szPassword, pswdBuf ); ::CryptHashData( hHash, (BYTE*)(char*)pswdBuf, pswdBuf.GetBufSize()-1, 0 ); #else ::CryptHashData( hHash, (B