CryptoAPI调用指南(三)——数字信封

五、 非对称加密
前面讲过,实际应用中非常对加解密都是以数字信封的方式出现的。

  1. CryptAcquireContext
  2. BOOL CryptEncryptMessage(
    PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara,
    DWORD cRecipientCert,
    PCCERT_CONTEXT [] rgpRecipientCert,
    const BYTE *pbToBeEncrypted,
    DWORD cbToBeEncrypted,
    BYTE *pbEncryptedBlob,
    DWORD *pcbEncryptedBlob
    )
    在CryptoAPI中只要调用这一个函数,就可以完成数字信封的生成。pEncryptPara是个结构体,用于设置各项加密参数。比如如下代码:
    CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams;
    DWORD EncryptAlgSize;
    CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm;
    DWORD EncryptParamsSize;
    EncryptAlgSize = sizeof(EncryptAlgorithm);
    memset(&EncryptAlgorithm, 0, EncryptAlgSize);
    EncryptAlgorithm.pszObjId = szOID_RSA_DES_EDE3_CBC;//设置对称加密算法和模式
    EncryptParamsSize = sizeof(EncryptParams);
    memset(&EncryptParams, 0, EncryptParamsSize);
    EncryptParams.cbSize = EncryptParamsSize;
    EncryptParams.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;//编码方式
    EncryptParams.hCryptProv = hCryptProv;//CSP句柄
    EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm;//指定算法
    如果对称加密使用RC2/RC4等流加密算法,还需要设置算法的加盐参数,比如:
    PCMSG_RC4_AUX_INFO pRC4Info = (PCMSG_RC4_AUX_INFO)malloc(sizeof(CMSG_RC4_AUX_INFO));
    pRC4Info->cbSize = sizeof(CMSG_RC4_AUX_INFO);
    pRC4Info->dwBitLen = 40;//算法将生成(128- dwBitLen)/8个字节长度的盐值,这里参数设置为40
    EncryptParams.pvEncryptionAuxInfo = pRC4Info;
    cRecipientCert是数字信封里接收者证书的个数,也就是rgpRecipientCert参数的元素个数;rgpRecipientCert是接收者证书数组;pbToBeEncrypted是被加密的原文;cbToBeEncrypted是原文长度;pbEncryptedBlob是加密后的密文;pcbEncryptedBlob是密文的长度。照例CryptEncryptMessage应调用两次,第一次调用时pbEncryptedBlob传NULL,pcbEncryptedBlob返回密文长度;第二次调用时为pbEncryptedBlob分配pcbEncryptedBlob个字节的长度。
    此方法同样调用成功返回true,否则返回false,并可以调用GetLastError返回具体错误信息。
    六、 非对称解密
    注意,和上面的功能不同,非对称解密时不需要调用CryptAcquireContext获得CSP句柄了。这是因为解密要用到私钥,使用私钥时系统自然就获得了其对应的CSP句柄。同理,后面讲到的数字签名也无需调用CryptAcquireContext。
    1 CertOpenStore
    调用CertOpenStore方法返回用来定位解密私钥对应证书的证书库。lpszStoreProvider传CERT_STORE_PROV_SYSTEM,dwEncodingType传0,hCryptProv传NULL,dwFlags传CERT_SYSTEM_STORE_CURRENT_USER,pvPara传“MY”。这样就打开了当前用户下的个人证书存储库。
    2.BOOL CryptDecryptMessage(
    PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara,
    const BYTE *pbEncryptedBlob,
    DWORD cbEncryptedBlob,
    BYTE *pbDecrypted,
    DWORD *pcbDecrypted,
    PCCERT_CONTEXT *ppXchgCert
    )
    先通过pDecryptPara设置解密参数。比如
    HCERTSTORE CertStoreArray[1];//声明一个证书库数组
    CRYPT_DECRYPT_MESSAGE_PARA DecryptParams;
    DWORD DecryptParamsSize = sizeof(DecryptParams);
    memset(&DecryptParams, 0, DecryptParamsSize);
    DecryptParams.cbSize = DecryptParamsSize;
    DecryptParams.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;//编码方式
    DecryptParams.cCertStore = 1;//支持查找多个证书库来定位私钥对应证书,因为一般只从个人证书存储库里查找,所以这里证书库数组元素个数设置为1
    CertStoreArray[0] = hStoreHandle;//将CertOpenStore返回的证书库添加到证书库数组
    DecryptParams.rghCertStore = CertStoreArray;//将证书库数组赋值给rghCertStore
    pbEncryptedBlob是密文;cbEncryptedBlob是密文长度;pbDecrypted是解密后的明文;pcbDecrypted是明文的长度;同样CryptDecryptMessage应调用两次,第一次时pbDecrypted传NULL,第二次调用时为pbDecrypted分配pcbDecrypted个字节的长度。ppXchgCert返回解密用的私钥对应的证书,如果不需要返回,可以传NULL。
    此方法的返回值与上面的相同。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_45303938

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值