CryptoAPI例子-最全3

// 设置加密参数
    CRYPT_ENCRYPT_MESSAGE_PARA EncryptPara;
    memset(&EncryptPara, 0, sizeof(EncryptPara));
    EncryptPara.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
    EncryptPara.dwMsgEncodingType = MY_ENCODING_TYPE;
    EncryptPara.hCryptProv = 0;
    EncryptPara.ContentEncryptionAlgorithm.pszObjId = szOID_RSA_DES_EDE3_CBC;
    EncryptPara.ContentEncryptionAlgorithm.Parameters.cbData = 0;
    EncryptPara.pvEncryptionAuxInfo = NULL;
    EncryptPara.dwFlags = 0;
    EncryptPara.dwInnerContentType = 0;

    // 设置加密的证书
    DWORD cRecipientCert;
    PCCERT_CONTEXT rgpRecipientCert[5];
    cRecipientCert = 1;
    rgpRecipientCert[0] = pReceiverCertContext;

    // 获取签名并加密消息长度
    CRYPT_DATA_BLOB encBlob;
    memset(&encBlob, 0, sizeof(encBlob));
    if(!CryptSignAndEncryptMessage(
        &SignPara,
        &EncryptPara,
        cRecipientCert,
        rgpRecipientCert,
        orgBlob.pbData,
        orgBlob.cbData,
        NULL,
        &encBlob.cbData))
    {
        delete [] orgBlob.pbData;
        CertFreeCertificateContext(pSignerCertContext);
        CertFreeCertificateContext(pReceiverCertContext);
        CertCloseStore(hCertStore, 0);
        CancelByError(L"Getting Signed&Encrypted message length failed.");
    }

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

    // 分配空间
    encBlob.pbData = (BYTE*) new char[encBlob.cbData];
    if(encBlob.pbData == NULL)
    {
        delete [] orgBlob.pbData;
        CertFreeCertificateContext(pSignerCertContext);
        CertFreeCertificateContext(pReceiverCertContext);
        CertCloseStore(hCertStore, 0);
        CancelByError(L"Memory allocation error while SignAndEncrypting. \n");
    }

    // 签名并加密消息
    if(!CryptSignAndEncryptMessage(
        &SignPara,
        &EncryptPara,
        cRecipientCert,
        rgpRecipientCert,
        orgBlob.pbData,
        orgBlob.cbData,
        encBlob.pbData,
        &encBlob.cbData))
    {
        delete [] orgBlob.pbData;
        delete [] encBlob.pbData;
        CertFreeCertificateContext(pSignerCertContext);
        CertFreeCertificateContext(pReceiverCertContext);
        CertCloseStore(hCertStore, 0);
        CancelByError(L"The message failed to sign and encrypt.");
    }

    _tprintf(L"The message is signed and encrypted.\n");

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

    // 清理
    delete [] orgBlob.pbData;
    delete [] encBlob.pbData;
    CertFreeCertificateContext(pSignerCertContext);
    CertFreeCertificateContext(pReceiverCertContext);
    CertCloseStore(hCertStore, 0);
}

// 解密并校验数字信封
void DecryptAndVerifyData(LPCSTR encFileName, LPCSTR orgFileName)
{
    // 准备数据
    CRYPT_DATA_BLOB encBlob;
    memset(&encBlob, 0, sizeof(encBlob));
    prepareData(NULL, 0, encFileName, encBlob.pbData, encBlob.cbData);

    // 存取证书库
    HCERTSTORE hCertStore = NULL;
    hCertStore = CertOpenStore(
        CERT_STORE_PROV_SYSTEM,
        0,
        NULL,
        CERT_SYSTEM_STORE_CURRENT_USER,
        L"my");
    if(hCertStore == NULL)
    {
        delete [] encBlob.pbData;
        CancelByError(L"The MY store could not be opened.");
    }

    // 设置解密参数
    CRYPT_DECRYPT_MESSAGE_PARA DecryptPara;
    memset(&DecryptPara, 0, sizeof(DecryptPara));
    DecryptPara.cbSize = sizeof(CRYPT_DECRYPT_MESSAGE_PARA);
    DecryptPara.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
    DecryptPara.cCertStore = 1;
    DecryptPara.rghCertStore = &hCertStore;

    // 设置校验参数
    CRYPT_VERIFY_MESSAGE_PARA VerifyPara;
    memset(&VerifyPara, 0, sizeof(VerifyPara));
    VerifyPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
    VerifyPara.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
    VerifyPara.hCryptProv = 0;
    VerifyPara.pfnGetSignerCertificate = NULL;
    VerifyPara.pvGetArg = NULL;

    // 获取解密消息长度
    DWORD dwSignerIndex = 0;
    CRYPT_DATA_BLOB orgBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    if(!(CryptDecryptAndVerifyMessageSignature(
        &DecryptPara,
        &VerifyPara,
        dwSignerIndex,
        encBlob.pbData,
        encBlob.cbData,
        NULL,           
        &orgBlob.cbData,
        NULL,
        NULL)))
    {
        delete [] encBlob.pbData;
        CertCloseStore(hCertStore, 0);
        CancelByError(L"Get decrypted message size failed.");
    }

    _tprintf(L"DecryptAndVerify message size is %d bytes.\n", orgBlob.cbData);

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

    // 解密并校验
    PCCERT_CONTEXT pRecverCert;
    PCCERT_CONTEXT pSignerCert;
    if(!(CryptDecryptAndVerifyMessageSignature(
        &DecryptPara,
        &VerifyPara,
        dwSignerIndex,
        encBlob.pbData,
        encBlob.cbData,
        orgBlob.pbData,           
        &orgBlob.cbData,
        &pRecverCert,
        &pSignerCert)))
    {
        delete [] orgBlob.pbData;
        delete [] encBlob.pbData;
        CertCloseStore(hCertStore, 0);
        CancelByError(L"The message failed to sign and encrypt.");
    }

    _tprintf(L"The message is decrypted and verifyed.\n");

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

    viewCertCN(pSignerCert);
    viewCertCN(pRecverCert);

    // 清理
    delete [] orgBlob.pbData;
    delete [] encBlob.pbData;
    CertCloseStore(hCertStore, 0);
}

// 加密并签名的数字信封(低级)
void EnvelopeData(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);

    // 从MY证书库获取签名者证书
    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"Open CertStore failed!\n");
    }

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

    _tprintf(L"Signer certificate has been found.\n");
    viewCertCN(pSignerCert);

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

    // 设置签名算法
    CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
    memset(&HashAlgorithm, 0, sizeof(HashAlgorithm));
    HashAlgorithm.pszObjId = szOID_RSA_MD5;

    // 设置签名编码参数
    CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo;
    CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1];
    memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
    SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
    SignerEncodeInfo.pCertInfo = pSignerCert->pCertInfo;
    SignerEncodeInfo.hCryptProv = hKeyProv;
    SignerEncodeInfo.dwKeySpec = AT_KEYEXCHANGE;
    SignerEncodeInfo.HashAlgorithm = HashAlgorithm;
    SignerEncodeInfo.pvHashAuxInfo = NULL;
    SignerEncodeInfoArray[0] = SignerEncodeInfo;
    
    // 设置签名证书
    CERT_BLOB SignerCertBlob;
    CERT_BLOB SignerCertBlobArray[1];
    SignerCertBlob.cbData = pSignerCert->cbCertEncoded;
    SignerCertBlob.pbData = pSignerCert->pbCertEncoded;
    SignerCertBlobArray[0] = SignerCertBlob;

    // 设置签名编码参数
    CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo;
    memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
    SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
    SignedMsgEncodeInfo.cSigners = 1;
    SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
    SignedMsgEncodeInfo.cCertEncoded = 1;
    SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;
    SignedMsgEncodeInfo.cCrlEncoded = 0;
    SignedMsgEncodeInfo.rgCrlEncoded = NULL;

    // 获取编码输出的签名块长度
    CRYPT_DATA_BLOB sigBlob;
    memset(&sigBlob, 0, sizeof(sigBlob));
    sigBlob.cbData = CryptMsgCalculateEncodedLength(
        MY_ENCODING_TYPE,
        0,
        CMSG_SIGNED,
        &SignedMsgEncodeInfo,
        NULL,
        orgBlob.cbData);
    if(sigBlob.cbData == 0)
    {
        delete [] orgBlob.pbData;
        CertFreeCertificateContext(pSignerCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Getting signed message length failed.");
    }

    // 分配编码空间
    sigBlob.pbData = (BYTE *) new char[sigBlob.cbData];
    if(sigBlob.pbData == NULL)
    {
        delete [] orgBlob.pbData;
        CertFreeCertificateContext(pSignerCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Memory allocation failed. \n");
    }

    // 编码签名消息
    HCRYPTMSG hMsg;
    hMsg = CryptMsgOpenToEncode(
        MY_ENCODING_TYPE,        // encoding type
        0,                       // flags
        CMSG_SIGNED,             // message type
        &SignedMsgEncodeInfo,    // pointer to structure
        NULL,                    // inner content OID
        NULL);                   // stream information (not used)
    if(hMsg == NULL) 
    {
        delete [] orgBlob.pbData;
        delete [] sigBlob.pbData;
        CertFreeCertificateContext(pSignerCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"The message to be encoded failed. \n");
    }

    // 添加数据
    if(!CryptMsgUpdate(
        hMsg,                // handle to the message
        orgBlob.pbData,        // pointer to the content
        orgBlob.cbData,        // size of the content
        TRUE))                // last call
    {
        delete [] orgBlob.pbData;
        delete [] sigBlob.pbData;
        CryptMsgClose(hMsg);
        CertFreeCertificateContext(pSignerCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"CryptMsgUpdate failed.\n");
    }

    // 获取签名结果
    if(!CryptMsgGetParam(
        hMsg,                        // handle to the message
        CMSG_CONTENT_PARAM,            // parameter type
        0,                            // index
        sigBlob.pbData,                // pointer to the BLOB
        &sigBlob.cbData))            // size of the BLOB
    {
        delete [] orgBlob.pbData;
        delete [] sigBlob.pbData;
        CryptMsgClose(hMsg);
        CertFreeCertificateContext(pSignerCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"CryptMsgGetParam signed message failed.\n");
    }

    // 清理签名部分
    delete [] orgBlob.pbData;

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

    if(hMsg != NULL)
    {
       CryptMsgClose(hMsg);
       hMsg = NULL;
    }

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

    // ----------------------- 签名结束:得到带原文的签名

    // 公钥加密

    // 查找接收者证书
    PCCERT_CONTEXT pRecverCert = NULL;
    pRecverCert = CertFindCertificateInStore(
       hCertStore,
       MY_ENCODING_TYPE,
       0,
       CERT_FIND_SUBJECT_STR,
       L"lny",
       NULL);
    if(pRecverCert == NULL)
    {
        delete [] sigBlob.pbData;
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Receiver certificate not found.");
    }

    _tprintf(L"Receiver certificate has been found.\n");
    viewCertCN(pRecverCert);

    // 设置加密证书
    PCERT_INFO RecipCertArray[1];
    RecipCertArray[0] = pRecverCert->pCertInfo;

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

    // 设置信封参数
    CMSG_ENVELOPED_ENCODE_INFO EnvelopedEncodeInfo;
    memset(&EnvelopedEncodeInfo, 0, sizeof(CMSG_ENVELOPED_ENCODE_INFO));
    EnvelopedEncodeInfo.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);
    EnvelopedEncodeInfo.hCryptProv = NULL;
    EnvelopedEncodeInfo.ContentEncryptionAlgorithm = ContentEncryptAlgorithm;
    EnvelopedEncodeInfo.pvEncryptionAuxInfo = NULL;
    EnvelopedEncodeInfo.cRecipients = 1;
    EnvelopedEncodeInfo.rgpRecipients = RecipCertArray;
    
    // 获取消息编码的长度
    CRYPT_DATA_BLOB encBlob;
    memset(&encBlob, 0, sizeof(encBlob));
    encBlob.cbData = CryptMsgCalculateEncodedLength(
        MY_ENCODING_TYPE,
        0,
        CMSG_ENVELOPED,
        &EnvelopedEncodeInfo,
        NULL,
        sigBlob.cbData);
    if(encBlob.cbData == 0)
    {
        delete [] sigBlob.pbData;
        CertFreeCertificateContext(pRecverCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Getting enveloped cbEncodedBlob length failed.");
    }

    _tprintf(L"Enveloped message size is %d bytes.", encBlob.cbData);

    // 分配编码空间
    encBlob.pbData = (BYTE *) new char[encBlob.cbData];
    if(encBlob.pbData == NULL)
    {
        delete [] sigBlob.pbData;
        CertFreeCertificateContext(pRecverCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Memory allocation failed. \n");
    }

    // 编码加密
    hMsg = CryptMsgOpenToEncode(
        MY_ENCODING_TYPE,        // encoding type
        0,                       // flags
        CMSG_ENVELOPED,          // message type
        &EnvelopedEncodeInfo,    // pointer to structure
        NULL,                     // szOID_RSA_signedData,    // inner content OID
        NULL);
    if(hMsg == NULL) 
    {
        delete [] encBlob.pbData;
        delete [] sigBlob.pbData;
        CertFreeCertificateContext(pRecverCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"The message open to be encode failed. \n");
    }

    // 添加数据
    if(!CryptMsgUpdate(
        hMsg,                // handle to the message
        sigBlob.pbData,        // pointer to the content
        sigBlob.cbData,        // size of the content
        TRUE))                // last call
    {
        delete [] encBlob.pbData;
        delete [] sigBlob.pbData;
        CryptMsgClose(hMsg);
        CertFreeCertificateContext(pRecverCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Enveloped CryptMsgUpdate failed.\n");
    }

    // 获取加密结果
    if(!CryptMsgGetParam(
        hMsg,                        // handle to the message
        CMSG_CONTENT_PARAM,            // parameter type
        0,                            // index
        encBlob.pbData,                // pointer to the BLOB
        &encBlob.cbData))            // size of the BLOB
    {
        delete [] encBlob.pbData;
        delete [] sigBlob.pbData;
        CryptMsgClose(hMsg);
        CertFreeCertificateContext(pRecverCert);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"CryptMsgGetParam enveloped message failed.\n");
    }

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

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

    if(hMsg != NULL)
    {
        CryptMsgClose(hMsg);
        hMsg = NULL;
    }

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

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

// 解密信封并校验签名(低级)
void DevelopeData(LPCSTR encFileName, LPCSTR orgFileName)
{
    // 准备数据
    CRYPT_DATA_BLOB encBlob;
    memset(&encBlob, 0, sizeof(encBlob));
    prepareData(NULL, 0, encFileName, encBlob.pbData, encBlob.cbData);

    // Open
    HCRYPTMSG hMsg = NULL; 
    hMsg = CryptMsgOpenToDecode( 
        MY_ENCODING_TYPE,    // Encoding type. 
        0,                    // Flags. 
        0,                    // Use the default message type which is listed in the message header. 
        NULL,                // Cryptographic provider. Use NULL for the default provider. 
        NULL,                // Recipient information. 
        NULL);                // Stream information. 
    if(hMsg == NULL) 
    { 
        delete [] encBlob.pbData;
        CancelByError(L"Failed in CryptMsgOpenToDecode."); 
    }

    // Update
    if(!CryptMsgUpdate( 
        hMsg,                // Handle to the message 
        encBlob.pbData,        // Pointer to the encoded BLOB 
        encBlob.cbData,        // Size of the encoded BLOB 
        TRUE))
    {
        delete [] encBlob.pbData;
        CryptMsgClose(hMsg);
        CancelByError(L"Failed in CryptMsgUpdate."); 
    }

    // 释放加密数据
    delete [] encBlob.pbData;

    // 开始操作解码后的加密数据 ================================

    // 消息类型
    DWORD dwType = 0; 
    DWORD dwSize = sizeof(dwType);
    if(!CryptMsgGetParam( 
        hMsg,                // Handle to the message 
        CMSG_TYPE_PARAM,    // Parameter type 
        0,                    // Index 
        &dwType,            // Buffer
        &dwSize))            // Size of the returned 
    { 
        CryptMsgClose(hMsg);
        CancelByError(L"Failed in CryptMsgGetParam for CMSG_TYPE_PARAM."); 
    }

    // 校验消息类型
    if (dwType != CMSG_ENVELOPED) 
    { 
        CryptMsgClose(hMsg);
        CancelByError(L"Not an enveloped data."); 
    }

    // 消息格式
    char szTypeName[1024];
    dwSize = 1024;
    if(!CryptMsgGetParam( 
        hMsg,                            // Handle to the message 
        CMSG_INNER_CONTENT_TYPE_PARAM,    // Parameter type 
        0,                                // Index 
        szTypeName,                        // Buffer 
        &dwSize))                        // Size of the returned 
    {
        CryptMsgClose(hMsg);
        CancelByError(L"Failed in CryptMsgGetParam for CMSG_INNER_CONTENT_TYPE_PARAM."); 
    }

    // 检查消息格式
    if(strcmp(szTypeName, szOID_PKCS_7_DATA) != 0) 
    {
//        CryptMsgClose(hMsg);
//      CancelByError(L"The inner content is not szOID_PKCS_7_DATA."); 
    }

    // 获取接收者证书大小
    if(!CryptMsgGetParam( 
        hMsg,                        // Handle to the message 
        CMSG_RECIPIENT_INFO_PARAM,    // Parameter type 
        0,                            // Index 
        NULL,                        // Buffer
        &dwSize))                    // Size of the returned 
    { 
        CryptMsgClose(hMsg);
        CancelByError(L"Failed in CryptMsgGetParam for CMSG_RECIPIENT_INFO_PARAM."); 
    }

    // 分配内存
    PCERT_INFO pRecverCertInfo = (PCERT_INFO) new char[dwSize]; 
    if (pRecverCertInfo == NULL)
    {
        CryptMsgClose(hMsg);
        CancelByError(L"Not enough memory."); 
    }

    // 获取接收者证书信息
    if(!CryptMsgGetParam( 
        hMsg,                        // Handle to the message 
        CMSG_RECIPIENT_INFO_PARAM,    // Parameter type 
        0,                            // Index 
        pRecverCertInfo,                    // Buffer
        &dwSize))                    // Size of the returned 
    { 
        delete [] pRecverCertInfo;
        CryptMsgClose(hMsg);
        CancelByError(L"Failed in CryptMsgGetParam for CMSG_RECIPIENT_INFO_PARAM."); 
    }

    // 访问证书库
    HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
    if(hCertStore == NULL)
    {
        delete [] pRecverCertInfo;
        CryptMsgClose(hMsg);
        CancelByError(L"Open CertStore failed!\n");
    }

    // 获取接收者证书
    PCCERT_CONTEXT hRcverCertContext = CertGetSubjectCertificateFromStore(hCertStore, MY_ENCODING_TYPE, pRecverCertInfo); 
    delete [] pRecverCertInfo;
    if(hRcverCertContext == NULL) 
    { 
        CryptMsgClose(hMsg);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"No matched certificate found in store."); 
    }

    viewCertCN(hRcverCertContext);

    // 申请私钥服务
    HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv = NULL;
    DWORD dwKeyType = 0;
    BOOL bFreeKeyProv = FALSE;
    if(!CryptAcquireCertificatePrivateKey(hRcverCertContext, 0, 0, &hCryptProv, &dwKeyType, &bFreeKeyProv))
    {
        CryptMsgClose(hMsg);
        CertFreeCertificateContext(hRcverCertContext);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Acquire certificate privateKey failed!\n");
    }

    /**//* ------ 另外一种申请私钥服务的做法:沒验证
            bReturn = CertGetCertificateContextProperty( 
                        context, 
                        CERT_KEY_PROV_INFO_PROP_ID , 
                        NULL, 
                        &dwSize 
                        ); 
            if (!bReturn) 
            { 
                CancelByError(L"Failed in CertGetCertificateContextProperty."); 
            }


            CRYPT_KEY_PROV_INFO * key_info = (CRYPT_KEY_PROV_INFO *) malloc (dwSize); 
            if (!key_info) 
                CancelByError(L"Not enough memory."); 
                     
            bReturn = CertGetCertificateContextProperty( 
                        context, 
                        CERT_KEY_PROV_INFO_PROP_ID , 
                        key_info, 
                        &dwSize 
                        ); 
            if (!bReturn) 
            { 
                CancelByError(L"Failed in CertGetCertificateContextProperty."); 
            }

            // acquire a CSP 
            HCRYPTPROV hCryptProv;

    bReturn = CryptAcquireContext(
        &hCryptProv,                // 返回的句柄
        NULL,                // CSP key 容器名称
        NULL,                // CSP 提供者名称
        PROV_RSA_FULL,        // CSP 提供者类型
        0);                    // 附加参数:

        bReturn = CryptAcquireContext( 
                        &hCryptProv, 
                        key_info->pwszContainerName, 
                        key_info->pwszProvName, 
                        key_info->dwProvType, 
                        key_info->dwFlags 
                        ); 
            if (!bReturn) 
            { 
                CancelByError(L"Failed in CryptAcquireContext."); 
            } 
*/

    // 解密解码的数据
    CMSG_CTRL_DECRYPT_PARA para; 
    para.cbSize = sizeof (CMSG_CTRL_DECRYPT_PARA); 
    para.dwKeySpec = dwKeyType; 
    para.hCryptProv = hCryptProv; 
    para.dwRecipientIndex = 0; 
    if(!CryptMsgControl( 
        hMsg,                // Handle to the message 
        0,                    // Flags 
        CMSG_CTRL_DECRYPT,    // Control type 
        &para))                // Pointer to the CERT_INFO 
    {
        CryptMsgClose(hMsg);
        CertFreeCertificateContext(hRcverCertContext);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Failed in CryptMsgControl."); 
    }

    // 获取解密消息大小
    CRYPT_DATA_BLOB sigBlob;
    memset(&sigBlob, 0, sizeof(sigBlob));
    if(!CryptMsgGetParam( 
        hMsg,                // Handle to the message 
        CMSG_CONTENT_PARAM, // Parameter type 
        0,                    // Index 
        NULL,                //
        &sigBlob.cbData))    // Size of the returned 
    {                    
        CryptMsgClose(hMsg);
        CertFreeCertificateContext(hRcverCertContext);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Failed in CryptMsgGetParam for CMSG_CONTENT_PARAM."); 
    }

    // 分配内存
    sigBlob.pbData = (BYTE *) new char[sigBlob.cbData];
    if(sigBlob.pbData == NULL)
    {
        CryptMsgClose(hMsg);
        CertFreeCertificateContext(hRcverCertContext);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Not enough memory."); 
    }

    // 获取解码消息
    if(!CryptMsgGetParam( 
        hMsg,                // Handle to the message 
        CMSG_CONTENT_PARAM, // Parameter type 
        0,                    // Index 
        sigBlob.pbData,        //
        &sigBlob.cbData))    // Size of the returned 
    {                    
        delete [] sigBlob.pbData;
        CryptMsgClose(hMsg);
        CertFreeCertificateContext(hRcverCertContext);
        CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
        CancelByError(L"Failed in CryptMsgGetParam for CMSG_CONTENT_PARAM."); 
    }

    // 清理解密过程数据
    CryptMsgClose(hMsg);
    CertFreeCertificateContext(hRcverCertContext);
    CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);

    _tprintf(L"Enveloped message decrypt successfully. \n");

    // ----------------------------------- 解密处理完成:得到一个带原文的签名

    // 解码带原文的数字签名
    hMsg = CryptMsgOpenToDecode( 
        MY_ENCODING_TYPE,    // Encoding type. 
        0,                    // Flags. 
        0,                    // Use the default message type which is listed in the message header. 
        NULL,                // Cryptographic provider. Use NULL for the default provider. 
        NULL,                // Recipient information. 
        NULL);                // Stream information. 
    if(hMsg == NULL) 
    { 
        delete [] sigBlob.pbData;
        CancelByError(L"Failed in CryptMsgOpenToDecode."); 
    }

    // Update
    if(!CryptMsgUpdate( 
        hMsg,                // Handle to the message 
        sigBlob.pbData,        // Pointer to the encoded BLOB 
        sigBlob.cbData,        // Size of the encoded BLOB 
        TRUE))
    {
        delete [] sigBlob.pbData;
        CryptMsgClose(hMsg);
        CancelByError(L"Failed in CryptMsgUpdate."); 
    }

    // 释放数字签名数据
    delete [] sigBlob.pbData;

    // 开始操作解码后的签名数据 ================================

    // 获取原文字节数
    CRYPT_DATA_BLOB orgBlob;
    memset(&orgBlob, 0, sizeof(orgBlob));
    if(!CryptMsgGetParam(
        hMsg,
        CMSG_CONTENT_PARAM,
        0,
        NULL,
        &orgBlob.cbData))
    {
        CryptMsgClose(hMsg);
        CancelByError(L"Get the decoded 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)
    {
        CryptMsgClose(hMsg);
        CancelByError(L"Not enough memory. \n");
    }

    // 获取原文
    if(!CryptMsgGetParam(
        hMsg,
        CMSG_CONTENT_PARAM,
        0,
        orgBlob.pbData,
        &orgBlob.cbData))
    {
        delete [] orgBlob.pbData;
        CryptMsgClose(hMsg);
        CancelByError(L"Get the decoded message failed. \n");
    }

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

    // 释放原文数据
    delete [] orgBlob.pbData;

    // 获取签名者证书信息大小
    DWORD cbSignerCertInfo;
    if(!CryptMsgGetParam(
        hMsg,                         // handle to the message
        CMSG_CERT_PARAM,              // parameter type
        0,                            // index
        NULL,   
        &cbSignerCertInfo))           // size of the returned 
    {
        CryptMsgClose(hMsg);
        CancelByError(L"Get SIGNER_CERT_INFO #1 failed.");
    }

    // 分配内存
    BYTE* pSignerCertInfo = (BYTE*) new char[cbSignerCertInfo];
    if(pSignerCertInfo == NULL)
    {
        CryptMsgClose(hMsg);
        CancelByError(L"Not enough memory."); 
    }

    // 获取签名者证书信息
    if(!CryptMsgGetParam(
        hMsg,                            // handle to the message
        CMSG_CERT_PARAM,                // parameter type
        0,                                // index
        pSignerCertInfo,   
        &cbSignerCertInfo))                // size of the returned 
    {
        delete [] pSignerCertInfo;
        CryptMsgClose(hMsg);
        CancelByError(L"Get SIGNER_CERT_INFO #1 failed.");
    }

    // 创建证书上下文
    PCCERT_CONTEXT pSignerCertContext = NULL;
    pSignerCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (BYTE*) pSignerCertInfo, cbSignerCertInfo);
    if(pSignerCertContext == NULL)
    {
        delete [] pSignerCertInfo;
        CryptMsgClose(hMsg);
        CancelByError(L"Get Subject Cert failed. ");
    }

    viewCertCN(pSignerCertContext);

    // 校验数字签名
    if(!CryptMsgControl(
        hMsg,
        0,
        CMSG_CTRL_VERIFY_SIGNATURE,
        pSignerCertContext->pCertInfo))
    {
        delete [] pSignerCertInfo;
        CryptMsgClose(hMsg);
        CertFreeCertificateContext(pSignerCertContext);
        CancelByError(L"Verify signature failed. \n");
    }

    _tprintf(L"Verify signature succeeded. \n");

    // 清理
    delete [] pSignerCertInfo;
    CryptMsgClose(hMsg);
    CertFreeCertificateContext(pSignerCertContext);
}

int _tmain(int argc, _TCHAR* argv[])
{
    // HASH
//    hashSHA1((BYTE*)"123456789012345", 15, NULL, "c:\\li.sha1");
//    hashSHA1(NULL, 0, "c:\\li.txt", "c:\\li.sha1");

    // Encrypt & Decrypt
//    DESEncrypt((BYTE*)"12345678", (BYTE*)"XXXXXXXX", (BYTE*)"123456789012345", 15, NULL, "c:\\li.des");
//    DESEncrypt((BYTE*)"12345678", (BYTE*)"XXXXXXXX", NULL, 0, "c:\\li.txt", "c:\\li.des");

//    AESEncrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX", (BYTE*)"123456789012345", 15, NULL, "c:\\li.aes");
//    AESEncrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX",  NULL, 0,  "c:\\1.txt", "c:\\li.aes");

//    BYTE* pEncData = (BYTE*) "\xCA\x89\x39\xC2\x2F\xB3\x4B\x39\x54\x2e\xd6\xb1\x14\xc9\x31\x10";
//    AESDecrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX", pEncData, 16, NULL, "c:\\li.org");
//    AESDecrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX", NULL, 0, "c:\\li.aes", "c:\\1.org");

    // CertStore & Cert
//    viewSystemCertStore(L"MY");
//    viewSystemCertStore(L"CA");
//    viewSystemCertStore(L"ROOT");
//    viewCrtCertStore(L"c:\\ca\\certs\\lny.crt");
//    viewCrtCertStore(L"c:\\cfcaT.p7b");
//    viewPfxCertStore("c:\\ca\\lny.pfx", L"welcome2008");

    // HASH SignData
//    BareSignData((BYTE*) "1234567890", 10, NULL, "c:\\li.sha1.sig");
//    VerifyBareSignData((BYTE*) "1234567890", 10, NULL, 0, NULL, "c:\\li.sha1.sig");
//    BareSignData(NULL, 0, "c:\\li.txt", "c:\\li.sha1.sig");
//    VerifyBareSignData(NULL, 0, NULL, 0, "c:\\li.txt", "c:\\li.sha1.sig");

    // TACHED SignData
//    SignData((BYTE*)"1234567890", 10, NULL, FALSE, "c:\\li.tch.sig");
//    VerifySignedData("c:\\li.tch.sig");
//    SignData(NULL, 0, "c:\\li.txt", FALSE, "c:\\li.tch.sig");
//    VerifySignedData("c:\\1li.tch.sig", "c:\\li.txt.org");

    // DETACHED SignData
//    SignData((BYTE*)"1234567890", 10, NULL, TRUE, "c:\\li.detch.sig");
//    VerifyDetachedSignData((BYTE*) "1234567890", 10, NULL, "c:\\li.detch.sig");
//    VerifyDetachedSignData(NULL, 0, "c:\\li.txt", "c:\\li.detch.sig");

    // Cert Encrypt & Decrypt
//    CertEncrypt((BYTE*)"1234567890", 10, NULL, "c:\\li.enc");
//    CertEncrypt(NULL, 0, "c:\\li.txt", "c:\\li.enc");
//    CertDecrypt("c:\\li.enc", "c:\\li.org");

//    SignAndEncryptData((BYTE*)"1234567890", 10, NULL, "c:\\li.enc");
//    DecryptAndVerifyData("c:\\li.enc", "c:\\li.org");

    printf("========================================================================\n");

    // Other cert Encrypt & Decrypt (低级消息函数)
//    EnvelopeData((BYTE*)"welcome2008WWWWW", 17, NULL, "c:\\li.enc");
    DevelopeData("c:\\li.enc", "c:\\li.org");

    pause();
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值