2012年7月5日星期四

CryptoAPI.Cpp


//引子,这些知识内容来源于网络加解密或其他的需要。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//示例一:加解密一个文件。
//本文精简自msdn。
//下一个版本的,即CNG,需要vista或者server 2008.或者特殊的开发包。
#include <windows.h>

void MyEncryptFile(LPTSTR pszSourceFile, LPTSTR pszDestinationFile, LPTSTR pszPassword)
    HCRYPTPROV hCryptProv = NULL; 
    CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,0);

    HCRYPTHASH hHash = NULL;
    CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash);
    CryptHashData(hHash, (BYTE *)pszPassword,lstrlen(pszPassword), 0);

    HCRYPTKEY hKey = NULL; 
    CryptDeriveKey(hCryptProv, CALG_RC4, hHash, 0x00800000, &hKey); 

    HANDLE hSourceFile = CreateFile(pszSourceFile, FILE_READ_DATA,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    HANDLE hDestinationFile = CreateFile(pszDestinationFile, FILE_WRITE_DATA,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

    PBYTE pbBuffer = (BYTE *)malloc(1000 - 1000 % 8 + 8);
    bool fEOF = FALSE;
    do 
    { 
        DWORD dwCount; 
        ReadFile(hSourceFile, pbBuffer, 1000 - 1000 % 8, &dwCount, NULL);
        if(dwCount < 1000 - 1000 % 8)   fEOF = TRUE;
        CryptEncrypt(hKey, NULL, fEOF,0, pbBuffer,&dwCount, 1000 - 1000 % 8 + 8);
        WriteFile(hDestinationFile, pbBuffer,dwCount,&dwCount,NULL);
    } while(!fEOF);

    CloseHandle(hDestinationFile);//立即写入文件。

void MyDecryptFile(LPTSTR pszSourceFile, LPTSTR pszDestinationFile, LPTSTR pszPassword)
{  
    HCRYPTPROV hCryptProv = NULL; 
    CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0);

    HCRYPTHASH hHash = NULL;
    CryptCreateHash(hCryptProv,CALG_MD5, 0, 0, &hHash);    
    CryptHashData(hHash, (BYTE *)pszPassword, lstrlen(pszPassword), 0);  

    HCRYPTKEY hKey = NULL; 
    CryptDeriveKey(hCryptProv, CALG_RC4,hHash, 0x00800000, &hKey); 

    HANDLE hSourceFile = CreateFile(pszSourceFile, FILE_READ_DATA,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    HANDLE hDestinationFile = CreateFile(pszDestinationFile,FILE_WRITE_DATA,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

    PBYTE pbBuffer = (PBYTE)malloc(1000 - 1000 % 8);
    bool fEOF = false;
    do
    {
        DWORD dwCount;
        ReadFile(hSourceFile, pbBuffer, 1000 - 1000 % 8, &dwCount, NULL);
        if(dwCount < 1000 - 1000 % 8)   fEOF = TRUE;        
        CryptDecrypt(hKey, 0, fEOF, 0, pbBuffer, &dwCount);         
        WriteFile(hDestinationFile, pbBuffer, dwCount,&dwCount,NULL);
    }while(!fEOF);

    CloseHandle(hDestinationFile);//立即写入文件。
}

int _tmain(int argc, _TCHAR* argv[])
{
    MyEncryptFile((LPTSTR)L"c:\\test.txt", (LPTSTR)L"c:\\en.txt", (LPTSTR)L"correy");
    MyDecryptFile((LPTSTR)L"c:\\en.txt", (LPTSTR)L"c:\\test_de.txt", (LPTSTR)L"correy");
    return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//示例二:加解密一段字符。//修改自msdn
#include <windows.h>
#pragma comment(lib, "crypt32.lib")

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

void main(void)
{
    BYTE* pbContent = (BYTE*) "This is a Encoding and Decoding a Hashed Message example from msdn\n"
        "made by correy;QQ:112426112;email:leguanyuan@126.com;website:http://correy.webs.com";
    DWORD cbContent = strlen((char *)pbContent)+1;  

    HCRYPTPROV hCryptProv;
    CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,0);

    CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
    DWORD HashAlgSize = sizeof(HashAlgorithm);
    memset(&HashAlgorithm, 0, HashAlgSize);   
    HashAlgorithm.pszObjId = szOID_RSA_MD5;  

    CMSG_HASHED_ENCODE_INFO HashedEncodeInfo;
    memset(&HashedEncodeInfo, 0, sizeof(CMSG_HASHED_ENCODE_INFO));
    HashedEncodeInfo.cbSize = sizeof(CMSG_HASHED_ENCODE_INFO);
    HashedEncodeInfo.hCryptProv = hCryptProv;
    HashedEncodeInfo.HashAlgorithm = HashAlgorithm;
    HashedEncodeInfo.pvHashAuxInfo = NULL;

    DWORD cbEncodedBlob = CryptMsgCalculateEncodedLength(MY_ENCODING_TYPE,0, CMSG_HASHED,&HashedEncodeInfo,NULL,cbContent);
    BYTE * pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob);

    HCRYPTMSG hMsg = CryptMsgOpenToEncode(MY_ENCODING_TYPE,0,CMSG_HASHED,&HashedEncodeInfo,NULL,NULL);
    CryptMsgUpdate(hMsg,pbContent,cbContent,TRUE);
    HCRYPTMSG hDupMsg = CryptMsgDuplicate(hMsg);

    CryptMsgGetParam(hDupMsg,CMSG_CONTENT_PARAM,0,pbEncodedBlob,&cbEncodedBlob);//加密 Encoding 
    CryptMsgClose(hMsg);
    CryptMsgClose(hDupMsg);//加密结束,下面是解密。

    hMsg = CryptMsgOpenToDecode(MY_ENCODING_TYPE,0,0,hCryptProv,NULL,NULL);
    CryptMsgUpdate(hMsg,pbEncodedBlob,cbEncodedBlob,TRUE); 

    DWORD cbData = sizeof(DWORD);
    DWORD dwMsgType;
    CryptMsgGetParam(hMsg,CMSG_TYPE_PARAM,0,&dwMsgType,&cbData);//if(dwMsgType == CMSG_HASHED) printf("The message is a hashed message. Proceed. \n");
    
    DWORD cbDecoded;
    CryptMsgGetParam(hMsg,CMSG_CONTENT_PARAM,0,NULL,&cbDecoded);//获取应得的内存大小。
    BYTE  * pbDecoded = (BYTE *) malloc(cbDecoded);

    CryptMsgGetParam(hMsg,CMSG_CONTENT_PARAM,0, pbDecoded,&cbDecoded);//解密 Decoding
    CryptMsgControl(hMsg,0,CMSG_CTRL_VERIFY_HASH,NULL);

    if(pbEncodedBlob)        free(pbEncodedBlob);
    if(pbDecoded)        free(pbDecoded);
    CryptMsgClose(hMsg); 
    if(hCryptProv)         CryptReleaseContext(hCryptProv,0);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//示例三:计算一个文件的MD5 hash,其实用这个dll里面的别的api也可以实现的。//修改自msdn
#include <windows.h>

DWORD main()
    HANDLE hFile = CreateFile(L"c:\\a.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);

    HCRYPTPROV hProv = 0;
    CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT);// Get handle to the crypto provider

    HCRYPTHASH hHash = 0;
    CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);

    BYTE rgbFile[1024] = {0};
    DWORD cbRead = 0;
    while (ReadFile(hFile, rgbFile, 1024, &cbRead, NULL))
    {
        if (0 == cbRead)          break;
        CryptHashData(hHash, rgbFile, cbRead, 0);
    }

    DWORD cbHash = 16;
    BYTE rgbHash[16];
    if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
    { //下面是显示。
        printf("MD5 hash of you select file is: ");
        for (DWORD i = 0; i < cbHash; i++)
        {
            CHAR rgbDigits[] = "0123456789abcdef";
            printf("%c%c", rgbDigits[rgbHash[i] >> 4],rgbDigits[rgbHash[i] & 0xf]);
        }
        //printf("\n");
    }

    CryptDestroyHash(hHash);
    CryptReleaseContext(hProv, 0);
    CloseHandle(hFile);
    return 0; 
}   
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//示例四:Example C++ Program: Creating an HMAC.made from msdn
#include <windows.h>

int main()
{      
    HCRYPTPROV  hProv       = NULL;
    CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT);

    HCRYPTHASH  hHash       = NULL;
    CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
    BYTE        Data1[]     = {0x70,0x61,0x73,0x73,0x77,0x6F,0x72,0x64};
    CryptHashData(hHash,Data1,sizeof(Data1),0); 
    HCRYPTKEY   hKey        = NULL;
    CryptDeriveKey(hProv, CALG_RC4, hHash, 0,  &hKey); 

    HMAC_INFO   HmacInfo;
    ZeroMemory(&HmacInfo, sizeof(HmacInfo));
    HmacInfo.HashAlgid = CALG_SHA1;

    HCRYPTHASH  hHmacHash   = NULL;
    CryptCreateHash(hProv,CALG_HMAC,hKey, 0, &hHmacHash);
    CryptSetHashParam(hHmacHash,HP_HMAC_INFO,(BYTE*)&HmacInfo,0);
    BYTE        Data2[]     = {0x6D,0x65,0x73,0x73,0x61,0x67,0x65};
    CryptHashData(hHmacHash,Data2,sizeof(Data2),0);

    DWORD       dwDataLen   = 0;
    CryptGetHashParam(hHmacHash,HP_HASHVAL,NULL,&dwDataLen,0);

    PBYTE       pbHash      = NULL;
    pbHash = (BYTE*)malloc(dwDataLen);
    CryptGetHashParam(hHmacHash,HP_HASHVAL,pbHash,&dwDataLen,0);

    printf("The hash is:  ");
    for(DWORD i = 0 ; i < dwDataLen ; i++) 
    {
        printf("%2.2x ",pbHash[i]);
    }
    printf("\n");

    if(hHmacHash)        CryptDestroyHash(hHmacHash);
    if(hKey)        CryptDestroyKey(hKey);
    if(hHash)        CryptDestroyHash(hHash);    
    if(hProv)        CryptReleaseContext(hProv, 0);
    if(pbHash)        free(pbHash);
    return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//暂时到此为止,以后可以添加和修改。

没有评论:

发表评论