CryptoAPI例子-最全2

// 裸签
void BareSignData(BYTE* orgData, int orgSize, LPCSTR inFileName = NULL, LPCSTR outFileName = NULL)
{
    // 准备数据
    CRYPT_DATA_BLOB orgBlob;
    prepareData(orgData, orgSize, inFileName, 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.");
    }

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

/**//*
BOOL WINAPI CryptAcquireCertificatePrivateKey(
  __in          PCCERT_CONTEXT pCert,
  __in          DWORD dwFlags,
  __in          void* pvReserved,
  __out         HCRYPTPROV_OR_NCRYPT_KEY_HANDLE* phCryptProvOrNCryptKey,
  __out         DWORD* pdwKeySpec,
  __out         BOOL* pfCallerFreeProvOrNCryptKey
);
*/
    // 请求证书私钥服务
    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");
    }

/**//*
BOOL WINAPI CryptSignHash(
  __in          HCRYPTHASH hHash,
  __in          DWORD dwKeySpec,
  __in          LPCTSTR sDescription,
  __in          DWORD dwFlags,
  __out         BYTE* pbSignature,
  __in_out      DWORD* pdwSigLen
);
*/

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

/**//*
BOOL WINAPI CryptImportPublicKeyInfo(
  __in          HCRYPTPROV hCryptProv,
  __in          DWORD dwCertEncodingType,
  __in          PCERT_PUBLIC_KEY_INFO pInfo,
  __out         HCRYPTKEY* phKey
);
*/
    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.");
    }

    // 校验签名
/**//*
BOOL WINAPI CryptVerifySignature(
  __in          HCRYPTHASH hHash,
  __in          BYTE* pbSignature,
  __in          DWORD dwSigLen,
  __in          HCRYPTKEY hPubKey,
  __in          LPCTSTR sDescription,
  __in          DWORD dwFlags
);
*/
    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.");
    }

/**//*
BOOL WINAPI CryptSignMessage(
  __in          PCRYPT_SIGN_MESSAGE_PARA pSignPara,
  __in          BOOL fDetachedSignature,
  __in          DWORD cToBeSigned,
  __in          const BYTE* rgpbToBeSigned[],
  __in          DWORD rgcbToBeSigned[],
  __out         BYTE* pbSignedBlob,
  __in_out      DWORD* pcbSignedBlob
);

typedef struct _CRYPT_SIGN_MESSAGE_PARA 
{  
    DWORD cbSize;  
    DWORD dwMsgEncodingType;  
    PCCERT_CONTEXT pSigningCert;  
    CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;  
    void* pvHashAuxInfo;  
    DWORD cMsgCert;  
    PCCERT_CONTEXT* rgpMsgCert;  
    DWORD cMsgCrl;  
    PCCRL_CONTEXT* rgpMsgCrl;  
    DWORD cAuthAttr;  
    PCRYPT_ATTRIBUTE rgAuthAttr;  
    DWORD cUnauthAttr;  
    PCRYPT_ATTRIBUTE rgUnauthAttr;  
    DWORD dwFlags;  
    DWORD dwInnerContentType;  
    CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;  
    void pvHashEncryptionAuxInfo;
} CRYPT_SIGN_MESSAGE_PARA;
*/

    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;

/**//*
    BOOL WINAPI CryptVerifyDetachedMessageSignature(
  __in          PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
  __in          DWORD dwSignerIndex,
  __in          const BYTE* pbDetachedSignBlob,
  __in          DWORD cbDetachedSignBlob,
  __in          DWORD cToBeSigned,
  __in          const BYTE* rgpbToBeSigned[],
  __in          DWORD rgcbToBeSigned[],
  __out_opt     PCCERT_CONTEXT* ppSignerCert
);
*/

    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;

/**//*
BOOL WINAPI CryptVerifyMessageSignature(
  __in          PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
  __in          DWORD dwSignerIndex,
  __in          const BYTE* pbSignedBlob,
  __in          DWORD cbSignedBlob,
  __out         BYTE* pbDecoded,
  __in_out      DWORD* pcbDecoded,
  __out_opt     PCCERT_CONTEXT* ppSignerCert
);
*/
    // 获取原文字节数
    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、付费专栏及课程。

余额充值