证书函数

15 篇文章 0 订阅

http://weng851217.blog.163.com/blog/static/884996120110205622778/

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

// 获取证书名称
void viewCertCN(PCCERT_CONTEXT hCert)
{

    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)
{

    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)
{

    // 获取解码后的长度
    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)
{

    // 校验证书日期
    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)
    {

        // 2.
        DWORD dwFlags = CERT_STORE_SIGNATURE_FLAG;
        PCCERT_CONTEXT hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, hCert, NULL, &dwFlags);
        if(hIssuserCert != NULL)
        {
            BOOL bCheckOK = FALSE;
            while(hIssuserCert != NULL)
            {
   
                // 校验证书签发者信息合法性
                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);
    }

    // 2.转换CRL数据为CRL句柄
    PCCRL_CONTEXT hCRL = CertCreateCRLContext(MY_ENCODING_TYPE, pbCrlData, cbCrlData);
    delete [] pbCrlData;
    if(hCRL != NULL)
    {

        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");
        }

   
        // 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)
{

    _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 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 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 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;
    }
}

 

http://weng851217.blog.163.com/blog/static/88499612011020573315/ 

// 查找证书
    PCCERT_CONTEXT hCert = CertFindCertificateInStore(
       hCertStore,
       MY_ENCODING_TYPE,
       0,
       CERT_FIND_SUBJECT_STR,
       L"lny",
       NULL);
    if(hCert == NULL)
    {
        delete [] orgBlob.pbData;
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Signer certificate not found.");
    }

    viewCertCN(hCert);
    viewCertIS(hCert);
    viewCertSN(hCert);
    viewCertDate(hCert);


    // 请求证书私钥服务
    HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;
    DWORD dwKeyType = 0;
    BOOL bFreeKeyProv = FALSE;
    if(!CryptAcquireCertificatePrivateKey(hCert, 0, 0, &hKeyProv, &dwKeyType, &bFreeKeyProv))
    {
        delete [] orgBlob.pbData;
        CertFreeCertificateContext(hCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Acquire certificate privateKey failed!\n");
    }

    // 创建离散对象
    HCRYPTHASH hHash = NULL;
    if(!CryptCreateHash(
        hKeyProv,                    // 容器句柄
        CALG_SHA1,                    // 算法标识
        NULL,                        // 算法使用的Key
        0,                            // 算法标识
        &hHash))                    // 返回的HASH对象
    {
        delete [] orgBlob.pbData;
        CertFreeCertificateContext(hCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Get SHA1 provider failed!\n");
    }

    // 计算数据摘要
    if(CryptHashData(hHash, orgBlob.pbData, orgBlob.cbData, 0) == 0)
    {
        delete [] orgBlob.pbData;
        CryptDestroyHash(hHash);
        CryptReleaseContext(hKeyProv, 0);
        CertFreeCertificateContext(hCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Calc SHA1 data failed!\n");
    }

    DWORD cbSign = 4096;
    BYTE  pbSign[4096];
    if(!CryptSignHash(hHash, dwKeyType, NULL, 0, pbSign, &cbSign))
    {
        delete [] orgBlob.pbData;
        CryptDestroyHash(hHash);
        CryptReleaseContext(hKeyProv, 0);
        CertFreeCertificateContext(hCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Calc SignData failed!\n");
    }

    reverse(pbSign, cbSign);
    showData(pbSign, cbSign);
    if(outFileName != NULL)
    {
        writeFile(outFileName, pbSign, cbSign);
    }

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

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

    if(hKeyProv != NULL && bFreeKeyProv)
    {
        CryptReleaseContext(hKeyProv, 0);
        hKeyProv = NULL;
    }

    if(hCert != NULL)
    {
        CertFreeCertificateContext(hCert);
        hCert = NULL;
    }

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

// 校验裸签名
void VerifyBareSignData(BYTE* orgData, int orgSize, BYTE* sigData, int sigSize, LPCSTR orgFileName = NULL, LPCSTR sigFileName = NULL)
{
    // 准备数据
    CRYPT_DATA_BLOB orgBlob, sigBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    memset(&sigBlob, 0, sizeof(sigBlob));
    prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
    prepareData(sigData, sigSize, sigFileName, sigBlob.pbData, sigBlob.cbData);
    reverse(sigBlob.pbData, sigBlob.cbData);

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

    // 创建离散对象
    HCRYPTHASH hHash = NULL;
    if(!CryptCreateHash(
        hProv,                        // 容器句柄
        CALG_SHA1,                    // 算法标识
        NULL,                        // 算法使用的Key
        0,                            // 算法标识
        &hHash))                    // 返回的HASH对象
    {
        delete [] orgBlob.pbData;
        delete [] sigBlob.pbData;
        CryptReleaseContext(hProv, 0);
        CancelByError(L"Get SHA1 provider failed!\n");
    }

    // 计算数据摘要
    if(CryptHashData(hHash, orgBlob.pbData, orgBlob.cbData, 0) == 0)
    {
        delete [] orgBlob.pbData;
        delete [] sigBlob.pbData;
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
        CancelByError(L"Calc SHA1 data failed!\n");
    }

    // 获取签名者证书公钥

    // 打开证书库
    HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_FILENAME, 0, NULL, 0, L"c:\\ca\\certs\\lny.crt");
    if(hCertStore == NULL)
    {
        delete [] orgBlob.pbData;
        delete [] sigBlob.pbData;
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
        CancelByError(L"Open CertStore failed!\n");
    }

    // 查找证书
    PCCERT_CONTEXT hCert = CertFindCertificateInStore(
       hCertStore,
       MY_ENCODING_TYPE,
       0,
       CERT_FIND_SUBJECT_STR,
       L"lny",
       NULL);
    if(hCert == NULL)
    {
        delete [] orgBlob.pbData;
        delete [] sigBlob.pbData;
        CryptDestroyHash(hHash);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CryptReleaseContext(hProv, 0);
        CancelByError(L"Signer certificate not found.\n");
    }


    HCRYPTKEY hPubKey;
    if(!CryptImportPublicKeyInfo(hProv, MY_ENCODING_TYPE, &hCert->pCertInfo->SubjectPublicKeyInfo, &hPubKey))
    {
        delete [] orgBlob.pbData;
        delete [] sigBlob.pbData;
        CryptDestroyKey(hPubKey);
        CryptDestroyHash(hHash);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CryptReleaseContext(hProv, 0);
        CancelByError(L"Get public key from cert failed.");
    }

    // 校验签名

    if(!CryptVerifySignature(hHash, sigBlob.pbData, sigBlob.cbData, hPubKey, NULL, 0))
    {
        _tprintf(L"Verify hash signature failed.\n");
    }
    else
    {
        _tprintf(L"Verify hash signature succeed.\n");
    }

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

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

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

    if(hCert != NULL)
    {
        CertFreeCertificateContext(hCert);
        hCert = NULL;
    }

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

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

// 含证书的签名(RSA/SHA1RSA)
void SignData(BYTE* orgData, int orgSize, LPCSTR orgFileName = NULL, BOOL bDetached = TRUE, LPCSTR sigFileName = NULL)
{
    // 准备数据
    CRYPT_DATA_BLOB orgBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);

    // 打开证书库
    HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
    if(hCertStore == NULL)
    {
        delete [] orgBlob.pbData;
        CancelByError(L"Open CertStore failed!\n");
    }

    // 查找证书
    PCCERT_CONTEXT hCert = CertFindCertificateInStore(
       hCertStore,
       MY_ENCODING_TYPE,
       0,
       CERT_FIND_SUBJECT_STR,
       L"lny",
       NULL);
    if(hCert == NULL)
    {
        delete [] orgBlob.pbData;
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Signer certificate not found.");
    }

    CRYPT_SIGN_MESSAGE_PARA  SigParams;
    SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
    SigParams.dwMsgEncodingType = MY_ENCODING_TYPE;
    SigParams.pSigningCert = hCert;
    SigParams.HashAlgorithm.pszObjId = szOID_RSA_SHA1RSA;
    SigParams.HashAlgorithm.Parameters.cbData = 0;
    SigParams.pvHashAuxInfo = NULL;
    SigParams.cMsgCert = 1;    // 签名中包含的证书数
    SigParams.rgpMsgCert = &hCert;
    SigParams.cMsgCrl = 0;    // 签名中包含的CRL数
    SigParams.rgpMsgCrl = NULL;
    SigParams.cAuthAttr = 0;
    SigParams.rgAuthAttr = NULL;
    SigParams.cUnauthAttr = 0;
    SigParams.rgUnauthAttr = NULL;
    SigParams.dwInnerContentType = 0;
    SigParams.dwFlags = 0;
    SigParams.pvHashAuxInfo = NULL;

    const BYTE* dataArray[1];
    DWORD_PTR sizeArray[1];
    dataArray[0] = orgBlob.pbData;
    sizeArray[0] = orgBlob.cbData;

    // 计算签名值的长度
    CRYPT_DATA_BLOB sigData;
    memset(&sigData, 0, sizeof(sigData));
    if(!CryptSignMessage(&SigParams, bDetached, 1, dataArray, sizeArray, NULL, &(sigData.cbData)))
    {
        delete [] orgBlob.pbData;
        CertFreeCertificateContext(hCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Get sign data size failed!\n");
    }

    // 分配内存
    sigData.pbData = (BYTE*) new char[sigData.cbData];
    if(sigData.pbData == NULL)
    {
        delete [] orgBlob.pbData;
        CertFreeCertificateContext(hCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Not enough memory. \n");
    }

    // 签名
    if(!CryptSignMessage(&SigParams, bDetached, 1, dataArray, sizeArray, sigData.pbData, &(sigData.cbData)))
    {
        delete [] orgBlob.pbData;
        delete [] sigData.pbData;
        CertFreeCertificateContext(hCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Sign data failed!\n");
    }

    showData(sigData.pbData, sigData.cbData);
    if(sigFileName != NULL)
    {
        writeFile(sigFileName, sigData.pbData, sigData.cbData);
    }

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

    if(hCert != NULL)
    {
        CertFreeCertificateContext(hCert);
        hCert = NULL;
    }

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

// 校验无原文的签名
void VerifyDetachedSignData(BYTE* orgData, DWORD orgSize, LPCSTR orgFileName, LPCSTR sigFileName)
{
    // 准备数据
    CRYPT_DATA_BLOB orgBlob, sigBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    memset(&sigBlob, 0, sizeof(sigBlob));
    prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
    prepareData(NULL, 0, sigFileName, sigBlob.pbData, sigBlob.cbData);

    // 设定校验参数
    CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
    VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
    VerifyParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
    VerifyParams.hCryptProv = 0;
    VerifyParams.pfnGetSignerCertificate = NULL;
    VerifyParams.pvGetArg = NULL;

    const BYTE* dataArray[1];
    DWORD_PTR   sizeArray[1];
    dataArray[0] = orgBlob.pbData;
    sizeArray[0] = orgBlob.cbData;

    PCCERT_CONTEXT hCert = NULL;
    if(CryptVerifyDetachedMessageSignature(
        &VerifyParams,
        0,
        sigBlob.pbData,
        sigBlob.cbData,
        1,
        dataArray,
        sizeArray,
        &hCert))
    {
        _tprintf(L"Verification message succeed.\n");
        viewCertCN(hCert);
    }
    else
    {
        _tprintf(L"Verification message failed.\n");
    }

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

    if(hCert != NULL)
    {
        CertFreeCertificateContext(hCert);
        hCert = NULL;
    }
}

// 校验含原文的签名
void VerifySignedData(LPCSTR sigFileName, LPCSTR orgFileName = NULL)
{
    // 准备数据
    CRYPT_DATA_BLOB sigBlob;
    memset(&sigBlob, 0, sizeof(sigBlob));
    prepareData(NULL, 0, sigFileName, sigBlob.pbData, sigBlob.cbData);

    // 设定校验参数
    CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
    VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
    VerifyParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
    VerifyParams.hCryptProv = 0;
    VerifyParams.pfnGetSignerCertificate = NULL;
    VerifyParams.pvGetArg = NULL;


    // 获取原文字节数
    CRYPT_DATA_BLOB orgBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    if(!CryptVerifyMessageSignature(
        &VerifyParams,
        0,
        sigBlob.pbData,
        sigBlob.cbData,
        NULL,
        &orgBlob.cbData,
        NULL))
    {
        delete [] sigBlob.pbData;
        CancelByError(L"Verification message failed. \n");
    }

    _tprintf(L"%d bytes needed for the decoded message.\n", orgBlob.cbData);

    // 分配内存
    orgBlob.pbData = (BYTE*) new char[orgBlob.cbData];
    if(orgBlob.pbData == NULL)
    {
        delete [] sigBlob.pbData;
        CancelByError(L"Not enough memory. \n");
    }

    PCCERT_CONTEXT hCert = NULL;
    if(CryptVerifyMessageSignature(
        &VerifyParams,
        0,
        sigBlob.pbData,
        sigBlob.cbData,
        orgBlob.pbData,
        &orgBlob.cbData,
        &hCert))
    {
        _tprintf(L"Verification message succeed. \n");
        showData(orgBlob.pbData, orgBlob.cbData);
        if(orgFileName != NULL)
        {
            writeFile(orgFileName, orgBlob.pbData, orgBlob.cbData);
        }

        viewCertCN(hCert);
    }
    else
    {
        _tprintf(L"Verification message failed. \n");
    }

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

    if(hCert != NULL)
    {
        CertFreeCertificateContext(hCert);
        hCert = NULL;
    }
}

// 使用证书公钥加密
void CertEncrypt(BYTE* orgData, int orgSize, LPCSTR orgFileName, LPCSTR encFileName = NULL)
{
    // 准备数据
    CRYPT_DATA_BLOB orgBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);

    // 获取CSP句柄
    HCRYPTPROV hCryptProv = NULL;
    if(!CryptAcquireContext(
        &hCryptProv,        // Address for handle to be returned.
        NULL,               // Use the current user's logon name.
        NULL,               // Use the default provider.
        PROV_RSA_FULL,      // Need to both encrypt and sign.
        NULL))              // No flags needed.
    {
        delete [] orgBlob.pbData;
        CancelByError(L"Cryptographic context could not be acquired.");
    }

    // 获取加密者证书
    HCERTSTORE hCertStore = NULL;
    hCertStore = CertOpenStore(
        CERT_STORE_PROV_SYSTEM,
        0,
        NULL,
        CERT_SYSTEM_STORE_CURRENT_USER,
        L"MY");
    if(hCertStore == NULL)
    {
        delete [] orgBlob.pbData;
        CryptReleaseContext(hCryptProv, 0);
        CancelByError(L"Open CertStore failed!\n");
    }

    // 查找签名者证书
    PCCERT_CONTEXT pCert = NULL;
    pCert = CertFindCertificateInStore(
       hCertStore,
       MY_ENCODING_TYPE,
       0,
       CERT_FIND_SUBJECT_STR,
       L"lny",
       NULL);
    if(pCert == NULL)
    {
        delete [] orgBlob.pbData;
        CryptReleaseContext(hCryptProv, 0);
        CancelByError(L"Encrypter certificate not found.");
    }

    _tprintf(L"Encrypter certificate has been found.\n");
    viewCertCN(pCert);

    // 设置加密算法
    CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm;
    memset(&EncryptAlgorithm, 0, sizeof(EncryptAlgorithm));
    EncryptAlgorithm.pszObjId = szOID_RSA_DES_EDE3_CBC;

    // 设置加密参数
    CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams;
    memset(&EncryptParams, 0, sizeof(EncryptParams));
    EncryptParams.cbSize =  sizeof(EncryptParams);
    EncryptParams.dwMsgEncodingType = PKCS_7_ASN_ENCODING;
    EncryptParams.hCryptProv = hCryptProv;
    EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm;

    // 设置加密的证书清单
    PCCERT_CONTEXT RecipientCertArray[1];
    RecipientCertArray[0] = pCert;

    // 获取加密消息的字节数
    CRYPT_DATA_BLOB encBlob;
    memset(&encBlob, 0, sizeof(encBlob));
    if(!CryptEncryptMessage(
        &EncryptParams,
        1,
        RecipientCertArray,
        orgBlob.pbData,
        orgBlob.cbData,
        NULL,
        &encBlob.cbData))
    {
        delete [] orgBlob.pbData;
        CryptReleaseContext(hCryptProv, 0);
        CancelByError(L"Getting encrypted message size failed.");
    }

    _tprintf(L"The encrypted message is %d bytes. \n",encBlob.cbData);

    // 分配空间
    encBlob.pbData = (BYTE*) new char[encBlob.cbData];
    if(encBlob.pbData == NULL)
    {
        delete [] orgBlob.pbData;
        CryptReleaseContext(hCryptProv, 0);
        CancelByError(L"Memory allocation error while encrypting.");
    }

    // 加密处理
    if(!CryptEncryptMessage(
        &EncryptParams,
        1,
        RecipientCertArray,
        orgBlob.pbData,
        orgBlob.cbData,
        encBlob.pbData,
        &encBlob.cbData))
    {
        delete [] orgBlob.pbData;
        delete [] encBlob.pbData;
        CryptReleaseContext(hCryptProv, 0);
        CancelByError(L"Encrypted message failed.");
    }

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

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

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

// 使用证书私钥解密
void CertDecrypt(LPCSTR encFileName, LPCSTR orgFileName)
{
    // 准备数据
    CRYPT_DATA_BLOB encBlob;
    memset(&encBlob, 0, sizeof(encBlob));
    prepareData(NULL, 0, encFileName, encBlob.pbData, encBlob.cbData);

    // 获取加密者证书
    HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
    if(hCertStore == NULL)
    {
        delete [] encBlob.pbData;
        CancelByError(L"Open CertStore failed!\n");
    }

    // 设置解密参数
    HCERTSTORE CertStoreArray[] = {hCertStore};
    CRYPT_DECRYPT_MESSAGE_PARA  DecryptParams;
    memset(&DecryptParams, 0, sizeof(DecryptParams));
    DecryptParams.cbSize = sizeof(DecryptParams);
    DecryptParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
    DecryptParams.cCertStore = 1;
    DecryptParams.rghCertStore = CertStoreArray;

    // 解密
    CRYPT_DATA_BLOB orgBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    if(!CryptDecryptMessage(
        &DecryptParams,
        encBlob.pbData,
        encBlob.cbData,
        NULL,
        &orgBlob.cbData,
        NULL))
    {
        delete [] encBlob.pbData;
        CancelByError(L"Error getting decrypted message size. \n");
    }

    _tprintf(L"The size for the decrypted message is: %d.\n", orgBlob.cbData);

    // 分配空间
    orgBlob.pbData = (BYTE*) new char[orgBlob.cbData];
    if(orgBlob.pbData == NULL)
    {
        delete [] encBlob.pbData;
        CancelByError(L"Memory allocation error while decrypting. \n");
    }

    // 解密
    if(!CryptDecryptMessage(
        &DecryptParams,
        encBlob.pbData,
        encBlob.cbData,
        orgBlob.pbData,
        &orgBlob.cbData,
        NULL))
    {
        delete [] encBlob.pbData;
        delete [] orgBlob.pbData;
        CancelByError(L"Decrypted message failed! \n");
    }

    _tprintf(L"Message Decrypted Successfully. %d\n", orgBlob.cbData);

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

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

// 证书加密并签名生成数字信封
void SignAndEncryptData(BYTE* orgData, int orgSize, LPCSTR orgFileName, LPCSTR encFileName)
{
    // 准备数据
    CRYPT_DATA_BLOB orgBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
   
    // 存取证书库
    HCERTSTORE hCertStore = NULL;
    hCertStore = CertOpenStore(
        CERT_STORE_PROV_SYSTEM,
        0,
        NULL,
        CERT_SYSTEM_STORE_CURRENT_USER,
        L"my");
    if(hCertStore == NULL)
    {
        delete [] orgBlob.pbData;
        CancelByError(L"The MY store could not be opened.");
    }

    // 获取签名者证书
    PCCERT_CONTEXT pSignerCertContext = NULL;
    pSignerCertContext = CertFindCertificateInStore(
        hCertStore,
        MY_ENCODING_TYPE,
        0,
        CERT_FIND_SUBJECT_STR,
        L"lny",
        NULL);
    if(pSignerCertContext == NULL)
    {
        delete [] orgBlob.pbData;
        CertCloseStore(hCertStore, 0);
        CancelByError(L"Signer cert not found.\n");
    }

    // 获取接收者证书
    PCCERT_CONTEXT pReceiverCertContext = NULL;
    pReceiverCertContext = CertFindCertificateInStore(
        hCertStore,
        MY_ENCODING_TYPE,
        0,
        CERT_FIND_SUBJECT_STR,
        L"lny",
        NULL);
    if(pReceiverCertContext == NULL)
    {
        delete [] orgBlob.pbData;
        CertFreeCertificateContext(pSignerCertContext);
        CertCloseStore(hCertStore, 0);
        CancelByError(L"Receiver cert not found.\n");
    }

    // pReceiverCertContext = pSignerCertContext;

    // 申请签名者私钥服务
    DWORD dwKeySpec;
    HCRYPTPROV hCryptProv;
    if(!CryptAcquireCertificatePrivateKey(
        pSignerCertContext,
        0,
        NULL,
        &hCryptProv,
        &dwKeySpec,
        NULL))
    {
        delete [] orgBlob.pbData;
        CertFreeCertificateContext(pSignerCertContext);
        CertFreeCertificateContext(pReceiverCertContext);
        CertCloseStore(hCertStore, 0);
        CancelByError(L"CryptAcquireCertificatePrivateKey.\n");
    }

    // 设置签名参数
    CRYPT_SIGN_MESSAGE_PARA SignPara;
    memset(&SignPara, 0, sizeof(SignPara));
    SignPara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
    SignPara.dwMsgEncodingType = MY_ENCODING_TYPE;
    SignPara.pSigningCert = pSignerCertContext ;
    SignPara.HashAlgorithm.pszObjId = szOID_RSA_MD2;
    SignPara.HashAlgorithm.Parameters.cbData = 0;
    SignPara.pvHashAuxInfo = NULL;
    SignPara.cMsgCert = 1;
    SignPara.rgpMsgCert = &pSignerCertContext ;
    SignPara.cMsgCrl = 0;
    SignPara.rgpMsgCrl = NULL;
    SignPara.cAuthAttr = 0;
    SignPara.rgAuthAttr = NULL;
    SignPara.cUnauthAttr = 0;
    SignPara.rgUnauthAttr = NULL;
    SignPara.dwFlags = 0;
    SignPara.dwInnerContentType = 0;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值