使用CryptDecryptMessage无法解密加密消息

我使用了微软上的数字信封的加解密函数,加密过程可以顺利完成但是解密数据时会报错:8009200c找不到可用于解密的证书和私钥。 这个问题是什么原因造成的,代码如下

//-------------------------------------------------------------------
// Copyright (C) Microsoft.  All rights reserved.
// Example of encrypting data and creating an enveloped 
// message using CryptEncryptMessage.
#pragma comment(lib, "crypt32.lib")

#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char* s);
PCCERT_CONTEXT GetRecipientCert(HCERTSTORE hCertStore);


void ByteToStr(
    DWORD cb,
    void* pv,
    LPSTR sz);

BOOL DecryptMessage(
    BYTE* pbEncryptedBlob,
    DWORD cbEncryptedBlob,
    HCRYPTPROV hCryptProv,
    HCERTSTORE hStoreHandle);

HCRYPTPROV GetCryptProv();

void main()
{
    //--------------------------------------------------------------------
    // 变量申明与初始化

    BYTE* pbContent = (BYTE*)"Security is our business.";// 待加密消息                                                
    DWORD cbContent = strlen((char*)pbContent) + 1;        // 消息长度                                                
    HCRYPTPROV hCryptProv;                                // CSP句柄
    HCERTSTORE hStoreHandle;                              //证书库句柄
    PCCERT_CONTEXT pRecipientCert;                        //接收证书
    PCCERT_CONTEXT RecipientCertArray[1];                 //接收证书列表
    DWORD EncryptAlgSize;
    CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm;
    CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams;
    DWORD EncryptParamsSize;
    BYTE* pbEncryptedBlob;
    DWORD    cbEncryptedBlob;



    printf("即将从消息 %s 开始.\n", pbContent);
    printf("这个消息的长度是 %d 字节. \n", cbContent);

    //获取加密服务者句柄
    hCryptProv = GetCryptProv();

    //--------------------------------------------------------------------
    // 打开系统证书库.

    if (hStoreHandle = CertOpenSystemStore(
        hCryptProv,
        "MY"))
    {
        printf(" MY 证书库已经打开. \n");
    }
    else
    {
        HandleError("获取证书库句柄出错.");
    }
    //--------------------------------------------------------------------
    // 调用函数GetRecipientCert获取接收者证书

    if (pRecipientCert = GetRecipientCert(
        hStoreHandle))
    {
        printf("接收者的证书已经获取. \n");
    }
    else
    {
        printf("No certificate with a CERT_KEY_CONTEXT_PROP_ID \n");
        printf("property and an AT_KEYEXCHANGE private key available. \n");
        printf("While the message could be encrypted, in this case, \n");
        printf("it could not be decrypted in this program. \n");
        printf("For more information, see the documentation for \n");
        printf("CrypteEncryptMessage and CryptDecryptMessage.\n\n");
        HandleError("No Certificate with AT_KEYEXCHANGE key in store.");
    }
    //--------------------------------------------------------------------
    // 创建接收证书列表.这里仅包含一个接收者证书
    RecipientCertArray[0] = pRecipientCert;

    //--------------------------------------------------------------------
    // 初始化算法结构.

    EncryptAlgSize = sizeof(EncryptAlgorithm);

    //--------------------------------------------------------------------
    // 初始化算法结构为0.

    memset(&EncryptAlgorithm, 0, EncryptAlgSize);

    //--------------------------------------------------------------------
    // 设置算法结构的必要的成员变量.

    EncryptAlgorithm.pszObjId = szOID_RSA_RC4;

    //--------------------------------------------------------------------
    // 初始化CRYPT_ENCRYPT_MESSAGE_PARA 结构. 

    EncryptParamsSize = sizeof(EncryptParams);
    memset(&EncryptParams, 0, EncryptParamsSize);
    EncryptParams.cbSize = EncryptParamsSize;
    EncryptParams.dwMsgEncodingType = MY_ENCODING_TYPE;
    EncryptParams.hCryptProv = hCryptProv;
    EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm;

    //--------------------------------------------------------------------
    // 调用 CryptEncryptMessage加密消息.

    //获取加密后数据长度
    if (CryptEncryptMessage(
        &EncryptParams,
        1,
        RecipientCertArray,//收件证书列表
        pbContent,
        cbContent,
        NULL,
        &cbEncryptedBlob))
    {
        printf("加密消息是 %d 字节. \n", cbEncryptedBlob);
    }
    else
    {
        HandleError("获取加密后数据块长度失败.");
    }
    //--------------------------------------------------------------------
    // 分配内存空间.

    if (pbEncryptedBlob = (BYTE*)malloc(cbEncryptedBlob))
    {
        printf("已经为加密数据块分配了内存空间. \n");
    }
    else
    {
        HandleError("加密时内存分配出错.");
    }
    //--------------------------------------------------------------------
    // 加密消息

    if (CryptEncryptMessage(
        &EncryptParams,
        1,
        RecipientCertArray,
        pbContent,
        cbContent,
        pbEncryptedBlob,
        &cbEncryptedBlob))
    {
        printf("加密成功. \n");
    }
    else
    {
        HandleError("加密失败.");
    }

    //--------------------------------------------------------------------
    // 调用DecryptMessage解密消息

    if (DecryptMessage(
        pbEncryptedBlob,
        cbEncryptedBlob,
        hCryptProv,
        hStoreHandle))
    {
        printf("解密成功. \n");
    }
    else
    {
        printf("解密失败. \n");
    }
    //--------------------------------------------------------------------
    //释放内存空间.

    CertFreeCertificateContext(pRecipientCert);
    if (CertCloseStore(
        hStoreHandle,
        CERT_CLOSE_STORE_CHECK_FLAG))
    {
        printf("MY证书库顺利关闭. \n");
    }
    else
    {
        printf("加密后证书库关闭 -- \n"
            "但是不是所有证书或证书撤消列表都被释放. \n");
    }
    if (hCryptProv)
    {
        CryptReleaseContext(hCryptProv, 0);
        printf("CSP句柄已经释放. \n");
    }
    else
    {
        printf("CSP句柄为空. \n");
    }
} // End of main

//--------------------------------------------------------------------
//  功能:解密用函数CryptDecryptMessage加密的消息.
//  参数
//        pbEncryptedBlob:待解密的消息
//        cbEncryptedBlob:待解密消息长度
//        hCryptProv:     CSP句柄
//        hStoreHandle:   已打开的证书库句柄
BOOL DecryptMessage(
    BYTE* pbEncryptedBlob,
    DWORD cbEncryptedBlob,
    HCRYPTPROV hCryptProv,
    HCERTSTORE hStoreHandle)
{
    //--------------------------------------------------------------------
    //申明与初始化变量
    DWORD cbDecryptedMessage;

    char* EncryptedString = (char*)malloc(sizeof(char) * (cbEncryptedBlob * 2 + 1));
    HCERTSTORE CertStoreArray[] = { hStoreHandle };
    CRYPT_DECRYPT_MESSAGE_PARA  DecryptParams;
    DWORD  DecryptParamsSize = sizeof(DecryptParams);
    BYTE* pbDecryptedMessage;
    LPSTR  DecryptedString;
    BOOL   fReturn = TRUE;


    ByteToStr(
        cbEncryptedBlob,
        pbEncryptedBlob,
        EncryptedString);

    //--------------------------------------------------------------------
    //打印转化后的密文.
    printf("加密后的字符串是: \n%s\n", EncryptedString);


    //--------------------------------------------------------------------
    //   初始化CRYPT_DECRYPT_MESSAGE_PARA结构.

    memset(&DecryptParams, 0, DecryptParamsSize);
    DecryptParams.cbSize = DecryptParamsSize;
    DecryptParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
    DecryptParams.cCertStore = 1;
    DecryptParams.rghCertStore = CertStoreArray;//证书库列表

    //--------------------------------------------------------------------
    //  解密消息数据.

    //  先调用CryptDecryptMessage确定解密后数据长度.
    if (CryptDecryptMessage(
        &DecryptParams,
        pbEncryptedBlob,
        cbEncryptedBlob,
        NULL,
        &cbDecryptedMessage,
        NULL))
    {
        printf("解密后数据的长度是: %d.\n", cbDecryptedMessage);
    }
    else
    {
        HandleError("获取解密后消息长度出错");
    }
    //--------------------------------------------------------------------
    // 分配空间

    if (pbDecryptedMessage = (BYTE*)malloc(
        cbDecryptedMessage))
    {
        printf("已经为解密消息分配了内存空间. \n");
    }
    else
    {
        HandleError("解密时内存分配出错");
    }
    //--------------------------------------------------------------------
    // 调用 CryptDecryptMessage 解密数据.

    if (CryptDecryptMessage(
        &DecryptParams,
        pbEncryptedBlob,
        cbEncryptedBlob,
        pbDecryptedMessage,
        &cbDecryptedMessage,
        NULL))
    {
        DecryptedString = (LPSTR)pbDecryptedMessage;
        printf("消息解密成功. \n");
        printf("被解密的字符串是: %s\n", DecryptedString);
    }
    else
    {
        printf("解密此消息出错 \n");
        printf("错误代码 %x \n", GetLastError());
        fReturn = FALSE;
    }

    //--------------------------------------------------------------------
    //释放内存空间

    free(pbEncryptedBlob);
    free(pbDecryptedMessage);
    return fReturn;
}  // End of DecryptMessage

//--------------------------------------------------------------------
// ByteToStr:  转换BYTE类型数组为字符串
//参数:cb[in]  需要转换的BYTE数组的长度
//      pv[in]  需要转换的BYTE数组指针
//      sz[out] 字符串指针
void ByteToStr(
    DWORD cb,
    void* pv,
    LPSTR sz)
{
    BYTE* pb = (BYTE*)pv;
    DWORD i;
    int b;

    for (i = 0; i < cb; i++)
    {
        //pb的前4位转换为字符
        b = (*pb & 0xF0) >> 4;
        *sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
        //pb的后4位转换为字符
        b = *pb & 0x0F;
        *sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
        pb++;
    }
    *sz++ = 0;
}



//--------------------------------------------------------------------
// 功能:遍历证书库中的证书,才,找到则返回此证书.  
// 参数:hCertStore 证书库句柄

PCCERT_CONTEXT GetRecipientCert(
    HCERTSTORE hCertStore)
{
    //-------------------------------------------------------------------- 
    // 申明与初始化变量

    PCCERT_CONTEXT pCertContext = NULL;
    BOOL fMore = TRUE;
    DWORD dwSize = 0;
    CRYPT_KEY_PROV_INFO* pKeyInfo = NULL;
    DWORD PropId = CERT_KEY_PROV_INFO_PROP_ID;

    //-------------------------------------------------------------------- 
    // 寻找包含交换密钥对的证书

    while (fMore && (pCertContext = CertFindCertificateInStore(
        hCertStore, // 证书库句柄. 
        0,          // 编码类型. 
        0,          // dwFindFlags. 说明查询标准,这里没有使用
        CERT_FIND_PROPERTY, // 查询类型,决定进行何种类型的查询。这里使用证书的特定扩展属性
        &PropId,    // pvFindPara. 给出查询的特定值,这里为 扩展属性的标识符
        pCertContext))) //证书句柄,第一次调用时为NULL ,之后为上一次返回的指针
    {
        //------------------------------------------------------------- 
        //  获取证书属性:密钥对信息

        if (!(CertGetCertificateContextProperty(
            pCertContext,
            CERT_KEY_PROV_INFO_PROP_ID,
            NULL, &dwSize)))
        {
            HandleError("获取密钥特性出错.");
        }

        //-------------------------------------------------------------- 
        // 分配空间

        if (pKeyInfo)
            free(pKeyInfo);
        if (!(pKeyInfo = (CRYPT_KEY_PROV_INFO*)malloc(dwSize)))
        {
            HandleError("为变量 pKeyInfo 分配内存出错.");
        }

        //-------------------------------------------------------------- 
        // 获取密钥信息块. 

        if (!(CertGetCertificateContextProperty(
            pCertContext,
            CERT_KEY_PROV_INFO_PROP_ID,
            pKeyInfo,
            &dwSize)))
        {
            HandleError("第二次调用此函数失败.");
        }

        //------------------------------------------- 
        // 检查密钥信息块是否包含交换密钥对. 

        if (pKeyInfo->dwKeySpec == AT_KEYEXCHANGE)
        {
            fMore = FALSE;
        }
    }    // End of while loop 

    if (pKeyInfo)
        free(pKeyInfo);
    return (pCertContext);
} // End of GetRecipientCert 


//获取加密提供者句柄
HCRYPTPROV GetCryptProv()
{
    HCRYPTPROV hCryptProv;           // 加密服务提供者句柄

    //获取加密提供者句柄
    if (CryptAcquireContext(
        &hCryptProv,         // 加密服务提供者句柄
        "ruanou",                // 密钥容器名,这里使用登陆用户名
        MS_ENHANCED_PROV,         // 加密服务提供者    
        PROV_RSA_FULL,       // 加密服务提供者类型,可以提供加密和签名等功能
        0))                  // 标志
    {
        printf("加密服务提供者句柄获取成功!\n");
    }
    else
    {


        //重新建立一个新的密钥集
        if (!CryptAcquireContext(&hCryptProv, "ruanou", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
        {
            HandleError("重新建立一个新的密钥集出错!");
        }

    }
    return hCryptProv;
}


//  HandleError:错误处理函数,打印错误信息,并退出程序
void HandleError(char* s)
{
    printf("程序执行发生错误!\n");
    printf("%s\n", s);
    printf("错误代码为: %x.\n", GetLastError());
    printf("程序终止执行!\n");
    exit(1);
}


就是CryptDecryptMessage()这个函数之后报的错误,请解答一下!