vc++网络安全编程范例(19)实现数字信封打包与拆解
数字信封是将对称密钥通过非对称加密(即:有公钥和私钥两个)的结果分发对称密钥的方法。
PKCS#7中将数字信封作为术语进行定义,而在正文中对进行了如下解释:数字信封包含被加密的内容和被加密的用于加密该内容的密钥。虽然经常使用接收方的公钥来加密“加密密钥”,但这并不是必须的,也可以使用发送方和接收方预共享的对称密钥来加密。当接收方收到数字信封时,先用私钥或预共享密钥解密,得到“加密密钥”,再用该密钥解密密文,获得原文。数字信封技术使用两层加密体系。
数字信封是一种综合利用了对称加密技术和非对称加密技术两者的优点进行信息安全传输的一种技术。数字信封既发挥了对称加密算法速度快、安全性好的优点,又发挥了非对称加密算法密钥管理方便的优点。
数字信封是公钥密码体制在实际中的一个应用,是用加密技术来保证只有规定的特定收信人才能阅读通信的内容。
在数字信封中,信息发送方采用对称密钥来加密信息内容,然后将此对称密钥用接收方的公开密钥来加密(这部分称数字信封)之后,将它和加密后的信息一起发送给接收方,接收方先用相应的私有密钥打开数字信封,得到对称密钥,然后使用对称密钥解开加密信息。这种技术的安全性相当高。数字信封主要包括数字信封打包和数字信封拆解,数字信封打包是使用对方的公钥将加密密钥进行加密的过程,只有对方的私钥才能将加密后的数据(通信密钥)还原;数字信封拆解是使用私钥将加密过的数据解密的过程。
数字信封的功能类似于普通信封,普通信封在法律的约束下保证只有收信人才能阅读信的内容;数字信封则采用密码技术保证了只有规定的接收人才能阅读信息的内容。数字信封中采用了对称密码体制和公钥密码体制。信息发送者首先利用随机产生的对称密码加密信息,再利用接收方的公钥加密对称密码,被公钥加密后的对称密码被称之为数字信封。在传递信息时,信息接收方若要解密信息,必须先用自己的私钥解密数字信封,得到对称密码,才能利用对称密码解密所得到的信息。这样就保证了数据传输的真实性和完整性。
在一些重要的电子商务交易中密钥必须经常更换,为了解决每次更换密钥的问题,结合对称加密技术和公开密钥技术的优点,它克服了秘密密钥加密中秘密密钥分发困难和公开密钥加密中加密时间长的问题,使用两个层次的加密来获得公开密钥技术的灵活性和秘密密钥技术高效性。信息发送方使用密码对信息进行加密,从而保证只有规定的收信人才能阅读信的内容。采用数字信封技术后,即使加密文件被他人非法截获,因为截获者无法得到发送方的通信密钥,故不可能对文件进行解密。
我们来用VC++实现数字信封打包与拆解,请见代码实现与注释讲解
#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()
{
//--------------------------------------------------------------------
// 变量申明与初始化 www.zzzyk.com
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
补充:综合编程 , 安全编程 ,