[MS Crypt API][原]计算文件hashParam

#define    SAIO_CSP                              "SAIO SignCSP"

typedef enum  Em_Algorithm_TYPE
{
    AlgorithmType_SHA1    = 1,
    AlgorithmType_SHA256  = 2
}ALGORITHM_TYPE, *PALGORITHM_TYPE;


BOOL GetFileHashParam(LPCSTR lpszCataFileName, PBYTE pbyHash, PDWORD pdwHashLen, ALGORITHM_TYPE emAlAlgorithmType)
{
    BOOL bRet = FALSE;
    HCRYPTPROV hProv = 0;
    HCRYPTHASH hHash = 0;
    HCRYPTKEY hKey = 0;
    HANDLE hFile = NULL;
    DWORD dwFileSize = 0, len;
    BYTE byTempBuf[2049] = {0};

    hFile = CreateFile(lpszCataFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == hFile)
    {
        return FALSE;
    }

    DWORD  dwProvType = PROV_RSA_AES;
    ALG_ID hashAlgo = CALG_SHA_256;
    if (AlgorithmType_SHA1 == emAlAlgorithmType)
    {
        dwProvType = PROV_RSA_FULL;
        hashAlgo = CALG_SHA1;
    }

    if (!CryptAcquireContext(&hProv, SAIO_CSP, NULL, dwProvType, 0)) 
    {
        if (GetLastError() == NTE_BAD_KEYSET)
        {
            if(!CryptAcquireContext(&hProv,SAIO_CSP,NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) 
            {
                goto HashExit;
            }
        }
    }

    // 
    //     Create a hash object.
    //     
    DWORD dwError = 0;
    if ( !CryptCreateHash(hProv, hashAlgo ,0 ,0 ,&hHash))
    {
        dwError = GetLastError();
        goto HashExit;
    }

    dwFileSize = GetFileSize(hFile, NULL);
    while(dwFileSize != 0)
    {
        bRet = ReadFile(hFile, byTempBuf, 2048, &len, NULL);
        // 
        //     Check for end of file. 
        //     
        if (bRet && len==0)
        {
            break;
        }

        CryptHashData(hHash, byTempBuf, len, 0);
        dwFileSize -= len;
    }

    if (hFile != NULL)
    {
        CloseHandle(hFile);
    }

    len = 0;
    DWORD dwCount = sizeof(DWORD);
    if(!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)pdwHashLen, &dwCount, 0))
    {
        *pdwHashLen = 0;
    }
    else
    {
        if (!CryptGetHashParam(hHash, HP_HASHVAL, pbyHash, pdwHashLen, 0))
        {
            *pdwHashLen = 0;
        }
    }

    if (*pdwHashLen != 20
        && *pdwHashLen != 32)
    {
        bRet = FALSE;
    }

HashExit:  
    if (hKey != NULL)
    {
        CryptDestroyKey(hKey);
    }

    if (hHash != NULL)
    {
        CryptDestroyHash(hHash);
    }

    if (hProv != NULL)
    {
        CryptReleaseContext(hProv, 0);
    }

    return bRet;
}

猜你喜欢

转载自jacky-dai.iteye.com/blog/1744160
ms