分享

CryptoAPI例子1

 株野 2019-03-12

来源:https://blog.csdn.net/dlfer11/article/details/50345035
标签:Windows,crypto API,示例
收藏:株野
作者: dlfer11
日期:2015年12月17日 17:54:59

MS CryptoAPI Samples 
// examCrypt.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

// Link with the Crypt32.lib file.
#pragma comment(lib, "Crypt32")
#pragma comment(lib, "comsuppw.lib")
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

//============================================================================================

// 暂停
void pause()
{
    _tprintf(L"\nPress ENTER key to continue \n");
    getchar();
}

// 错误报告
void CancelByError(TCHAR* str)
{
    _tprintf(L"\nFAULT:\n");
    _tprintf(L"An error occurred in running the program. \n");
    _tprintf(L"%s", str);
    _tprintf(L"Error number %x. \n", GetLastError());
    _tprintf(L"Program terminating. \n");
    pause();
    exit(1);
}

// 字节反序
void reverse(BYTE* data, int nLen)
{
    for(int ii=0; ii < nLen/2; ii++)
    {
        BYTE c = data[ii];
        data[ii] = data[nLen -ii -1];
        data[nLen -ii -1] = c;
    }
}

// 输出文件
void writeFile(const char* sFileName, BYTE* data, DWORD nSize)
{
    FILE* fp = fopen(sFileName, "wb");
    if(fp == NULL)
    {
        printf("Can not open output file '%s'! \n", sFileName);
        return;
    }

    if(fwrite(data, 1, nSize, fp) != nSize)
    {
        fclose(fp);
        printf("Write to file '%s' failed! \n", sFileName);
        return;
    }

    fclose(fp);
    printf("Write %d bytes to file '%s'! \n", nSize, sFileName);
}

// 读取文件(data = NULL for get file size ONLY)
void readFile(const char* sFileName, BYTE* data, DWORD & nSize)
{
    nSize = 0;

    FILE* fp = fopen(sFileName, "rb");
    if(fp == NULL)
    {
        printf("Can not open input file '%s'! \n", sFileName);
        return;
    }

    fseek(fp, 0, SEEK_END);
    nSize = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    if(data != NULL)
    {
        if(fread(data, 1, nSize, fp) != nSize)
        {
            fclose(fp);
            printf("Read from file '%s' failed! \n", sFileName);
            return;
        }
        printf("Read %d bytes from file '%s'! \n", nSize, sFileName);
    }
    fclose(fp);
}

// 显示HEX码
void showData(BYTE* data, DWORD nSize)
{
    printf("\n****\n");
    for(DWORD ii=0; ii < nSize; ii++)
    {
        printf("%02x ", data[ii]);
        if((ii+1) % 16 ==0) printf("\n");
    }
    printf("\n**** %d bytes\n", nSize);
}

// 准备数据(Auto new outData)
void prepareData(BYTE* inData, DWORD inSize, LPCSTR inFileName, BYTE* &outData, DWORD& outSize)
{
    if(inData == NULL && inFileName != NULL)
    {
        // Read from file
        readFile(inFileName, NULL, outSize);
        if(outSize != 0)
        {
            outData = (BYTE*) new char[outSize];
            if(outData == NULL)    CancelByError(L"Not enough memory. \n");
            readFile(inFileName, outData, outSize);
        }
    }
    else
    {
        // Read from buffer
        outSize = inSize;
        outData = (BYTE*) new char[outSize];
        if(outData == NULL)    CancelByError(L"Not enough memory. \n");
        memcpy(outData, inData, outSize);
    }
}

//=====================================================================================================

//============================ 离散算法

// SHA1 
void hashSHA1(BYTE* inData, int inSize, LPCSTR inFileName = NULL, LPCSTR outFileName = NULL)
{
    // 准备数据
    CRYPT_DATA_BLOB orgBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    prepareData(inData, inSize, inFileName, orgBlob.pbData, orgBlob.cbData);

/**//*
BOOL WINAPI CryptAcquireContext(
  __out         HCRYPTPROV* phProv,
  __in          LPCTSTR pszContainer,
  __in          LPCTSTR pszProvider,
  __in          DWORD dwProvType,
  __in          DWORD dwFlags
);
*/
    // 获取CSP句柄
    HCRYPTPROV hProv = NULL; 
    if(!CryptAcquireContext(
        &hProv,                // 返回的句柄
        NULL,                // CSP 容器名称
        NULL,                // CSP 提供者名称
        PROV_RSA_FULL,        // CSP 提供者类型
        0))                    // 附加参数:
    {
        delete [] orgBlob.pbData;
        CancelByError(L"Get CSP provider context failed! \n");
    }

/**//*
BOOL WINAPI CryptCreateHash(
__in          HCRYPTPROV hProv,
__in          ALG_ID Algid,
__in          HCRYPTKEY hKey,
__in          DWORD dwFlags,
__out         HCRYPTHASH* phHash
);
*/
    // 创建HASH句柄
    HCRYPTHASH hHash = NULL;
    if(!CryptCreateHash(
        hProv,                // 容器句柄 
        CALG_SHA1,            // 算法标识
        NULL,                // 算法使用的Key
        0,                    // 算法标识
        &hHash))            // 返回的HASH对象
    {
        delete [] orgBlob.pbData;
        CryptReleaseContext(hProv, 0);
        CancelByError(L"Get SHA1 provider failed!\n");
    }

/**//*
BOOL WINAPI CryptHashData(
  __in          HCRYPTHASH hHash,
  __in          BYTE* pbData,
  __in          DWORD dwDataLen,
  __in          DWORD dwFlags
);
*/
    // 添加HASH内容
    if(!CryptHashData(hHash, orgBlob.pbData, orgBlob.cbData, 0))
    {
        delete [] orgBlob.pbData;
        CryptReleaseContext(hProv, 0);
        CancelByError(L"Calc SHA1 data failed!\n");
    }

/**//* TODO: Calc other blocks
    if(CryptHashData(hHash, (BYTE*) "12345", 5, 0) == 0)
    {
        CancelByError(L"Calc SHA1 data failed!\n");
        return; 
    }
*/

/**//*
BOOL WINAPI CryptGetHashParam(
  __in          HCRYPTHASH hHash,
  __in          DWORD dwParam,
  __out         BYTE* pbData,
  __in_out      DWORD* pdwDataLen,
  __in          DWORD dwFlags
);
*/
    // 获取HASH值
    BYTE byHashVal[21];    // SHA1 output have 20 bytes. 
    memset(byHashVal, 0x00, 21); 
    DWORD dwDataLen = 20; 
    if(!CryptGetHashParam(hHash, HP_HASHVAL, byHashVal, &dwDataLen, 0))
    {
        delete [] orgBlob.pbData;
        CryptDestroyHash(hHash); 
        CryptReleaseContext(hProv, 0);
        CancelByError(L"Calc SHA1 data failed!\n");
    }

    showData(byHashVal, dwDataLen);
    if(outFileName != NULL)
    {
        writeFile(outFileName, byHashVal, dwDataLen);
    }

    // 清理

    delete [] orgBlob.pbData;

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

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

// ============================ 对称加密解密

// DES(CBC/PKCS5Padding)
void DESEncrypt(BYTE* key, BYTE* iv, BYTE* inData, int inSize, LPCSTR inFileName = NULL, LPCSTR outFileName = NULL)
{
    // 准备数据
    CRYPT_DATA_BLOB orgBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    prepareData(inData, inSize, inFileName, orgBlob.pbData, orgBlob.cbData);

/**//*
BOOL WINAPI CryptAcquireContext(
  __out         HCRYPTPROV* phProv,
  __in          LPCTSTR pszContainer,
  __in          LPCTSTR pszProvider,
  __in          DWORD dwProvType,
  __in          DWORD dwFlags
);
*/

    // 获取CSP句柄
    HCRYPTPROV hProv = NULL; 
    if(!CryptAcquireContext(
        &hProv,                // 返回的句柄
        NULL,                // CSP 容器名称
        NULL,                // CSP 提供者名称
        PROV_RSA_FULL,        // CSP 提供者类型
        0))                    // 附加参数:
    {
        delete [] orgBlob.pbData;
        CancelByError(L"Get CSP provider context failed!\n");
    }

    // 创建 Key
    struct keyBlob
    {
        BLOBHEADER hdr;
        DWORD cbKeySize;
        BYTE rgbKeyData[8];
    } keyBlob;

    keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
    keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
    keyBlob.hdr.reserved = 0;
    keyBlob.hdr.aiKeyAlg = CALG_DES;
    keyBlob.cbKeySize = 8;
    CopyMemory(keyBlob.rgbKeyData, key, keyBlob.cbKeySize);

/**//*
BOOL WINAPI CryptImportKey(
  __in          HCRYPTPROV hProv,
  __in          BYTE* pbData,
  __in          DWORD dwDataLen,
  __in          HCRYPTKEY hPubKey,
  __in          DWORD dwFlags,
  __out         HCRYPTKEY* phKey
);
*/

    HCRYPTKEY hKey = NULL;
    if (!CryptImportKey(hProv, (BYTE*)(&keyBlob), sizeof(keyBlob), NULL, CRYPT_EXPORTABLE, &hKey))
    {
        delete [] orgBlob.pbData;
        CryptReleaseContext(hProv, 0);
        CancelByError(L"Create key failed!\n");
    }

/**//*
BOOL WINAPI CryptSetKeyParam(
  __in          HCRYPTKEY hKey,
  __in          DWORD dwParam,
  __in          const BYTE* pbData,
  __in          DWORD dwFlags
);
*/

    // 设置初始向量
    if(iv == NULL)
    {
        if(!CryptSetKeyParam(hKey, KP_IV, key, 0))
        {
            delete [] orgBlob.pbData;
            CryptDestroyKey(hKey);
            CryptReleaseContext(hProv, 0);
            CancelByError(L"Set key's IV parameter failed!\n");
        }
    }
    else
    {
        if(!CryptSetKeyParam(hKey, KP_IV, iv, 0))
        {
            delete [] orgBlob.pbData;
            CryptDestroyKey(hKey);
            CryptReleaseContext(hProv, 0);
            CancelByError(L"Set key's IV parameter failed!\n");
        }
    }

/**//*
BOOL WINAPI CryptEncrypt(
  __in          HCRYPTKEY hKey,
  __in          HCRYPTHASH hHash,
  __in          BOOL Final,
  __in          DWORD dwFlags,
  __in_out      BYTE* pbData,
  __in_out      DWORD* pdwDataLen,
  __in          DWORD dwBufLen
);
*/

    // 加密处理
    CRYPT_DATA_BLOB encBlob;
    memset(&encBlob, 0, sizeof(encBlob));
    encBlob.cbData = orgBlob.cbData;
    encBlob.pbData = (BYTE*) new char[(orgBlob.cbData/8+1)*8];
    memcpy(encBlob.pbData, orgBlob.pbData, orgBlob.cbData);
    if(!CryptEncrypt(hKey, NULL, TRUE, 0, encBlob.pbData, &encBlob.cbData, (orgBlob.cbData/8+1)*8))
    {
        delete [] orgBlob.pbData;
        delete [] encBlob.pbData;
        CryptDestroyKey(hKey);
        CryptReleaseContext(hProv, 0);
        CancelByError(L"DES encrypt failed!\n");
    }

    showData(encBlob.pbData, encBlob.cbData);
    if(outFileName != NULL)
    {
        writeFile(outFileName, encBlob.pbData, encBlob.cbData);
    }

    // 清理

    delete [] orgBlob.pbData;
    delete [] encBlob.pbData;

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

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

// AES-128/CBC/PKCS5Padding
// AES-256: KeySize=256, IVSize=128, Result=128
void AESEncrypt(BYTE* key, BYTE* iv, BYTE* inData, int inSize, LPCSTR inFileName = NULL, LPCSTR outFileName = NULL)
{
    // 准备数据
    CRYPT_DATA_BLOB orgBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    prepareData(inData, inSize, inFileName, orgBlob.pbData, orgBlob.cbData);

/**//*
BOOL WINAPI CryptAcquireContext(
  __out         HCRYPTPROV* phProv,
  __in          LPCTSTR pszContainer,
  __in          LPCTSTR pszProvider,
  __in          DWORD dwProvType,
  __in          DWORD dwFlags
);
*/

    HCRYPTPROV hProv = NULL; 
    if(!CryptAcquireContext(
        &hProv,                // 返回的句柄
        NULL,                // CSP 容器名称
        NULL,                // CSP 提供者名称
        PROV_RSA_AES,        // CSP 提供者类型
        0))            // 附加参数:
    {
        delete [] orgBlob.pbData;
        CancelByError(L"Get provider context failed!\n");
    }

    // 创建 Key
    struct keyBlob
    {
        BLOBHEADER hdr;
        DWORD cbKeySize;
        BYTE rgbKeyData[16];                // FOR AES-256 = 32
    } keyBlob;

    keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
    keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
    keyBlob.hdr.reserved = 0;
    keyBlob.hdr.aiKeyAlg = CALG_AES_128;    // FOR AES-256 = CALG_AES_256
    keyBlob.cbKeySize = 16;                    // FOR AES-256 = 32
    CopyMemory(keyBlob.rgbKeyData, key, keyBlob.cbKeySize);

/**//*
BOOL WINAPI CryptImportKey(
  __in          HCRYPTPROV hProv,
  __in          BYTE* pbData,
  __in          DWORD dwDataLen,
  __in          HCRYPTKEY hPubKey,
  __in          DWORD dwFlags,
  __out         HCRYPTKEY* phKey
);
*/

    HCRYPTKEY hKey = NULL;
    if (!CryptImportKey(hProv, (BYTE*)(&keyBlob), sizeof(keyBlob), NULL, CRYPT_EXPORTABLE, &hKey))
    {
        delete [] orgBlob.pbData;
        CryptReleaseContext(hProv, 0);
        CancelByError(L"Create key failed!\n");
    }

/**//*
BOOL WINAPI CryptSetKeyParam(
  __in          HCRYPTKEY hKey,
  __in          DWORD dwParam,
  __in          const BYTE* pbData,
  __in          DWORD dwFlags
);
*/

    // 设置初始向量
    if(iv == NULL)
    {
        if(!CryptSetKeyParam(hKey, KP_IV, key, 0))
        {
            delete [] orgBlob.pbData;
            CryptDestroyKey(hKey);
            CryptReleaseContext(hProv, 0);
            CancelByError(L"Set key's IV parameter failed!\n");
        }
    }
    else
    {
        if(!CryptSetKeyParam(hKey, KP_IV, iv, 0))
        {
            delete [] orgBlob.pbData;
            CryptDestroyKey(hKey);
            CryptReleaseContext(hProv, 0);
            CancelByError(L"Set key's IV parameter failed!\n");
        }
    }

/**//*
BOOL WINAPI CryptEncrypt(
  __in          HCRYPTKEY hKey,
  __in          HCRYPTHASH hHash,
  __in          BOOL Final,
  __in          DWORD dwFlags,
  __in_out      BYTE* pbData,
  __in_out      DWORD* pdwDataLen,
  __in          DWORD dwBufLen
);
*/

    // 加密处理
    CRYPT_DATA_BLOB encBlob;
    memset(&encBlob, 0, sizeof(encBlob));
    encBlob.cbData = orgBlob.cbData;
    encBlob.pbData = (BYTE*) new char[(orgBlob.cbData/16+1)*16];
    memcpy(encBlob.pbData, orgBlob.pbData, orgBlob.cbData);
    if(!CryptEncrypt(hKey, NULL, TRUE, 0, encBlob.pbData, &encBlob.cbData, (orgBlob.cbData/16+1)*16))
    {
        delete [] orgBlob.pbData;
        delete [] encBlob.pbData;
        CryptDestroyKey(hKey);
        CryptReleaseContext(hProv, 0);
        CancelByError(L"AES encrypt failed!\n");
    }

    showData(encBlob.pbData, encBlob.cbData);
    if(outFileName != NULL)
    {
        writeFile(outFileName, encBlob.pbData, encBlob.cbData);
    }

    // 释放获取的对象
    delete [] orgBlob.pbData;
    delete [] encBlob.pbData;

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

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

// AES-128/CBC/PKCS5Padding
// AES-256: KeySize=256, IVSize=128, Result=128
void AESDecrypt(BYTE* key, BYTE* iv, BYTE* inData, int inSize, LPCSTR inFileName = NULL, LPCSTR outFileName = NULL)
{
    // 准备数据
    CRYPT_DATA_BLOB encBlob;
    memset(&encBlob, 0, sizeof(encBlob));
    prepareData(inData, inSize, inFileName, encBlob.pbData, encBlob.cbData);

/**//*
BOOL WINAPI CryptAcquireContext(
  __out         HCRYPTPROV* phProv,
  __in          LPCTSTR pszContainer,
  __in          LPCTSTR pszProvider,
  __in          DWORD dwProvType,
  __in          DWORD dwFlags
);
*/

    HCRYPTPROV hProv = NULL; 
    if(!CryptAcquireContext(
        &hProv,                // 返回的句柄
        NULL,                // CSP key 容器名称
        NULL,                // CSP 提供者名称
        PROV_RSA_AES,        // CSP 提供者类型
        0))            // 附加参数:
    {
        delete [] encBlob.pbData;
        CancelByError(L"Get provider context failed!\n");
    }

    // 创建 Key
    struct keyBlob
    {
        BLOBHEADER hdr;
        DWORD cbKeySize;
        BYTE rgbKeyData[16];                // FOR AES-256 = 32
    } keyBlob;

    keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
    keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
    keyBlob.hdr.reserved = 0;
    keyBlob.hdr.aiKeyAlg = CALG_AES_128;    // FOR AES-256 = CALG_AES_256
    keyBlob.cbKeySize = 16;                    // FOR AES-256 = 32
    CopyMemory(keyBlob.rgbKeyData, key, keyBlob.cbKeySize);

/**//*
BOOL WINAPI CryptImportKey(
  __in          HCRYPTPROV hProv,
  __in          BYTE* pbData,
  __in          DWORD dwDataLen,
  __in          HCRYPTKEY hPubKey,
  __in          DWORD dwFlags,
  __out         HCRYPTKEY* phKey
);
*/

    HCRYPTKEY hKey = NULL;
    if (!CryptImportKey(hProv, (BYTE*)(&keyBlob), sizeof(keyBlob), NULL, CRYPT_EXPORTABLE, &hKey))
    {
        delete [] encBlob.pbData;
        CryptReleaseContext(hProv, 0);
        CancelByError(L"Create key failed!\n");
    }

/**//*
BOOL WINAPI CryptSetKeyParam(
  __in          HCRYPTKEY hKey,
  __in          DWORD dwParam,
  __in          const BYTE* pbData,
  __in          DWORD dwFlags
);
*/

    // 设置初始向量
    if(iv == NULL)
    {
        if(!CryptSetKeyParam(hKey, KP_IV, key, 0))
        {
            delete [] encBlob.pbData;
            CryptDestroyKey(hKey);
            CryptReleaseContext(hProv, 0);
            CancelByError(L"Set key's IV parameter failed!\n");
        }
    }
    else
    {
        if(!CryptSetKeyParam(hKey, KP_IV, iv, 0))
        {
            delete [] encBlob.pbData;
            CryptDestroyKey(hKey);
            CryptReleaseContext(hProv, 0);
            CancelByError(L"Set key's IV parameter failed!\n");
        }
    }

/**//*
BOOL WINAPI CryptDecrypt(
  __in          HCRYPTKEY hKey,
  __in          HCRYPTHASH hHash,
  __in          BOOL Final,
  __in          DWORD dwFlags,
  __in_out      BYTE* pbData,
  __in_out      DWORD* pdwDataLen
);
*/

    // 加密处理
    CRYPT_DATA_BLOB orgBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    orgBlob.cbData = encBlob.cbData;
    orgBlob.pbData = (BYTE*) new char[encBlob.cbData];
    memcpy(orgBlob.pbData, encBlob.pbData, encBlob.cbData);
    if(!CryptDecrypt(hKey, NULL, TRUE, 0, orgBlob.pbData, &orgBlob.cbData))
    {
        delete [] orgBlob.pbData;
        delete [] encBlob.pbData;
        CryptDestroyKey(hKey);
        CryptReleaseContext(hProv, 0);
        CancelByError(L"AES encrypt failed!\n");
    }

    showData(orgBlob.pbData, orgBlob.cbData);
    if(outFileName != NULL)
    {
        writeFile(outFileName, orgBlob.pbData, orgBlob.cbData);
    }

    // 清理
    delete [] orgBlob.pbData;
    delete [] encBlob.pbData;

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

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

// ============================ 证书管理

// 获取证书名称
void viewCertCN(PCCERT_CONTEXT hCert)
{
/**//*
DWORD WINAPI CertGetNameString(
  __in          PCCERT_CONTEXT pCertContext,
  __in          DWORD dwType,
  __in          DWORD dwFlags,
  __in          void* pvTypePara,
  __out         LPTSTR pszNameString,
  __in          DWORD cchNameString
);
*/

    TCHAR sName[1024];
    DWORD nNameSize = 1000;
    DWORD nNameType = 0;                // CERT_X500_NAME_STR for FULL name, like C=.., O=.., OU=.., CN=,
    nNameSize = CertGetNameString(
        hCert,
        CERT_NAME_SIMPLE_DISPLAY_TYPE,    // CERT_NAME_RDN_TYPE for FULL name.
        0,
        &nNameType,
        sName,
        nNameSize);

    _tprintf(L"CN: %s\n", sName); 
}

// 获取证书签发者
void viewCertIS(PCCERT_CONTEXT hCert)
{
/**//*
DWORD WINAPI CertGetNameString(
  __in          PCCERT_CONTEXT pCertContext,
  __in          DWORD dwType,
  __in          DWORD dwFlags,
  __in          void* pvTypePara,
  __out         LPTSTR pszNameString,
  __in          DWORD cchNameString
);
*/

    TCHAR sName[1024];
    DWORD nNameSize = 1000;
    DWORD nNameType = 0;                // CERT_X500_NAME_STR for FULL name, like C=.., O=.., OU=.., CN=,
    nNameSize = CertGetNameString(
        hCert,
        CERT_NAME_SIMPLE_DISPLAY_TYPE,    // CERT_NAME_RDN_TYPE for FULL name.
        CERT_NAME_ISSUER_FLAG,
        &nNameType,
        sName,
        nNameSize);
    
    _tprintf(L"IS: %s\n", sName); 
}

// 获取证书序列号
void viewCertSN(PCCERT_CONTEXT hCert)
{
/**//*
BOOL WINAPI CryptFormatObject(
  __in          DWORD dwCertEncodingType,
  __in          DWORD dwFormatType,
  __in          DWORD dwFormatStrType,
  __in          void* pFormatStruct,
  __in          LPCSTR lpszStructType,
  __in          const BYTE* pbEncoded,
  __in          DWORD cbEncoded,
  __out         void* pbFormat,
  __in_out      DWORD* pcbFormat
);
*/
    // 获取解码后的长度
    CRYPT_INTEGER_BLOB  SerialNumber;
    BOOL bRet = FALSE;
    bRet = CryptFormatObject(
        hCert->dwCertEncodingType,
        0,
        0,
        NULL,
        0,
        hCert->pCertInfo->SerialNumber.pbData,
        hCert->pCertInfo->SerialNumber.cbData,
        NULL,
        &SerialNumber.cbData);
    if(!bRet)
    {
        CancelByError(L"Get SerialNumber decode length failed!\n");
    }

    // 分配解码空间
    SerialNumber.pbData = (BYTE*) new char[SerialNumber.cbData];

    // 获取解码数据
    bRet = CryptFormatObject(
        hCert->dwCertEncodingType,
        0,
        0,
        NULL,
        0,
        hCert->pCertInfo->SerialNumber.pbData,
        hCert->pCertInfo->SerialNumber.cbData,
        SerialNumber.pbData,
        &SerialNumber.cbData);
    if(!bRet)
    {
        delete [] SerialNumber.pbData;
        CancelByError(L"SerialNumber decode failed!\n");
    }

//    char* tmpStr = _com_util::ConvertBSTRToString((BSTR)SerialNumber.pbData);
    _tprintf(L"SN: %s\n", SerialNumber.pbData);

    delete [] SerialNumber.pbData;
//    delete [] tmpStr;
}

// 获取证书有效期
void viewCertDate(PCCERT_CONTEXT hCert)
{
    CTime dtBefore(hCert->pCertInfo->NotBefore);
    CTime dtAfter(hCert->pCertInfo->NotAfter);
    _tprintf(L"DT: %s TO %s\n", dtBefore.Format(L"%Y-%m-%d %H:%M:%S"), dtAfter.Format(L"%Y-%m-%d %H:%M:%S"));
}

// 校验证书合法性
void verifyCert(PCCERT_CONTEXT hCert)
{
/**//*
LONG WINAPI CertVerifyTimeValidity(
  __in          LPFILETIME pTimeToVerify,
  __in          PCERT_INFO pCertInfo
);
*/
    // 校验证书日期
    int nRetCode = CertVerifyTimeValidity(NULL, hCert->pCertInfo);
    if(nRetCode < 0)
    {
        _tprintf(L"Verify cert's date failed: BEFORE date after TODAY!\n");
    }

    if(nRetCode > 0)
    {
        _tprintf(L"Verify cert's date failed: Cert has expired!\n");
    }

    if(nRetCode == 0)
    {
        _tprintf(L"Verify cert's date succeed!\n");
    }

    // 校验签名者证书

    HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"ROOT");
    if(hCertStore != NULL)
    {
/**//*
PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(
  __in          HCERTSTORE hCertStore,
  __in          PCCERT_CONTEXT pSubjectContext,
  __in_opt      PCCERT_CONTEXT pPrevIssuerContext,
  __in_out      DWORD* pdwFlags
);
*/
        // 2.
        DWORD dwFlags = CERT_STORE_SIGNATURE_FLAG;
        PCCERT_CONTEXT hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, hCert, NULL, &dwFlags); 
        if(hIssuserCert != NULL)
        {
            BOOL bCheckOK = FALSE;
            while(hIssuserCert != NULL)
            {
    /**//*
    BOOL WINAPI CertVerifySubjectCertificateContext(
      __in          PCCERT_CONTEXT pSubject,
      __in_opt      PCCERT_CONTEXT pIssuer,
      __in_out      DWORD* pdwFlags
    );
    */
                // 校验证书签发者信息合法性
                dwFlags = CERT_STORE_SIGNATURE_FLAG;
                if(CertVerifySubjectCertificateContext(hCert, hIssuserCert, &dwFlags))
                {
                    if(dwFlags == 0)
                    {
                        _tprintf(L"Verify cert by issuser's cert succeed! \n");
                        bCheckOK = TRUE;
                        break;
                    }
                }
                else
                {
                    _tprintf(L"Verify cert by issuser's cert failed! \n");
                    break;
                }

                // Next ..
                hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, hCert, hIssuserCert, &dwFlags); 
            }

            if(!bCheckOK)
            {
                _tprintf(L"Verify cert by issuser's cert failed! \n");
            }

        }
        else
        {
            _tprintf(L"Can not find cert issuser's cert!\n");
        }

        if(hIssuserCert != NULL)
        {
            CertFreeCertificateContext(hIssuserCert);
            hIssuserCert = NULL;
        }
    }
    else
    {
        _tprintf(L"Open ROOT CertStore failed!\n");
    }

    if(hCertStore != NULL)
    {
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        hCertStore = NULL;
    }


    // 校验 CRL 列表

    // 1.
    BYTE* pbCrlData = NULL;
    DWORD cbCrlData = 0;
    readFile("c:\\cfcaT.crl", NULL, cbCrlData);
    if(cbCrlData > 0)
    {
        pbCrlData = (BYTE*) new char[cbCrlData];
        readFile("c:\\cfcaT.crl", pbCrlData, cbCrlData);
    }

/**//*
PCCRL_CONTEXT WINAPI CertCreateCRLContext(
  __in          DWORD dwCertEncodingType,
  __in          const BYTE* pbCrlEncoded,
  __in          DWORD cbCrlEncoded
);
*/

    // 2.转换CRL数据为CRL句柄
    PCCRL_CONTEXT hCRL = CertCreateCRLContext(MY_ENCODING_TYPE, pbCrlData, cbCrlData);
    delete [] pbCrlData;
    if(hCRL != NULL)
    {
/**//*
    BOOL WINAPI CertIsValidCRLForCertificate(
  __in          PCCERT_CONTEXT pCert,
  __in          PCCRL_CONTEXT pCRL,
  __in          DWORD dwFlags,
  __in          void* pvReserved
*/
        if(CertIsValidCRLForCertificate(hCert, hCRL, 0, NULL))
        {
            _tprintf(L"CRL is valid for the cert!\n");
        }
        else
        {
            _tprintf(L"CRL is invalid for the cert!!\n");
        }

    /**//*
    BOOL WINAPI CertFindCertificateInCRL(
      __in          PCCERT_CONTEXT pCert,
      __in          PCCRL_CONTEXT pCrlContext,
      __in          DWORD dwFlags,
      __in_opt      void* pvReserved,
      __out         PCRL_ENTRY* pCrlEntry
    );
    */
        // Step 4: 检查CRL是否包含该证书
        PCRL_ENTRY pCrlEntry = NULL;
        if(CertFindCertificateInCRL(hCert, hCRL, 0, 0, &pCrlEntry))
        {
            if(pCrlEntry != NULL)
            {
                _tprintf(L"Cert has been revoked!\n");
            }
            else
            {
                _tprintf(L"Cert not be revoked!\n");
            }
        }
        else
        {
            _tprintf(L"Find cert in CRL failed!\n");
        }
    }
    else
    {
        _tprintf(L"Create CRL context failed!\n");
    }

    if(hCRL != NULL)
    {
        CertFreeCRLContext(hCRL);
    }
}

// ============================ 证书库管理

// 列出证书库证书
void listCerts(HCERTSTORE hCertStore)
{
/**//*
PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(
  __in          HCERTSTORE hCertStore,
  __in          PCCERT_CONTEXT pPrevCertContext
);
*/
    _tprintf(L"======== L I S T   C E R T   I N   S T O R E ========\n");

    int nCnt = 0;
    PCCERT_CONTEXT hCert = NULL; 
    while(hCert = CertEnumCertificatesInStore(hCertStore, hCert))
    {
        viewCertCN(hCert);
        viewCertIS(hCert);
        viewCertSN(hCert);
        viewCertDate(hCert);
        verifyCert(hCert);
        ++ nCnt;
        _tprintf(L"-----------------------------\n");
    }

    _tprintf(L"**** Count: %d \n", nCnt);

    // 清理
    if(hCert != NULL)
    {
        CertFreeCertificateContext(hCert);
        hCert = NULL;
    }
}

// 列出系统证书库证书
void viewSystemCertStore(LPCTSTR storeName)
{
/**//*
HCERTSTORE WINAPI CertOpenStore(
  __in          LPCSTR lpszStoreProvider,
  __in          DWORD dwMsgAndCertEncodingType,
  __in          HCRYPTPROV_LEGACY hCryptProv,
  __in          DWORD dwFlags,
  __in          const void* pvPara
);
*/

    // 打开证书库
    HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, storeName);
    if(hCertStore == NULL)
    {
        CancelByError(L"Open CertStore failed!\n");
    }

    listCerts(hCertStore);

    // 清理
    if(hCertStore != NULL)
    {
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        hCertStore = NULL;
    }
}

// 文件证书库(CRT/P7B)
void viewCrtCertStore(LPCTSTR crtFileName)
{
/**//*
HCERTSTORE WINAPI CertOpenStore(
  __in          LPCSTR lpszStoreProvider,
  __in          DWORD dwMsgAndCertEncodingType,
  __in          HCRYPTPROV_LEGACY hCryptProv,
  __in          DWORD dwFlags,
  __in          const void* pvPara
);
*/

    // 打开证书库
    HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_FILENAME, 0, NULL, 0, crtFileName);
    if(hCertStore == NULL)
    {
        CancelByError(L"Open CertStore failed!\n");
    }

    listCerts(hCertStore);

    // 清理
    if(hCertStore != NULL)
    {
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        hCertStore = NULL;
    }
}

// 证书库文件(PFX)
void viewPfxCertStore(LPCSTR sCertFileName, LPCTSTR sCertPassword)
{
    // 读取证书库文件
    CRYPT_DATA_BLOB pfxData;
    memset(&pfxData, 0, sizeof(pfxData));
    readFile(sCertFileName, NULL, pfxData.cbData);
    if(pfxData.cbData > 0)
    {
        pfxData.pbData = (BYTE*) new char[pfxData.cbData];
        readFile(sCertFileName, pfxData.pbData, pfxData.cbData);
    }

/**//*
HCERTSTORE WINAPI PFXImportCertStore(
  __in          CRYPT_DATA_BLOB* pPFX,
  __in          LPCWSTR szPassword,
  __in          DWORD dwFlags
);
*/

    HCERTSTORE hCertStore = PFXImportCertStore(&pfxData, sCertPassword, 0);
    delete [] pfxData.pbData;
    if(hCertStore == NULL)
    {
        CancelByError(L"Open CertStore failed!\n");
    }

    // 列出证书
    listCerts(hCertStore);

    // 清理
    if(hCertStore != NULL)
    {
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        hCertStore = NULL;
    }
}

// ================================= 数据签名、核签、加密、解密、数字信封

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多