// 设置加密参数
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
¶)) // 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;
}