证书是通过BSI API(gscBsiPkiGetCertificate
)从智能卡获得的,我试图获取其公钥/私钥对的密钥句柄,以使用CryptoAPI执行非对称加密操作&# 39; s CryptEncrypt
和CryptDecrypt
函数。
gscBsiPkiGetCertificate
以十六进制编码形式返回原始证书数据,我能够对其进行解码并成功调用CertCreateCertificateContext
以获取CERT_CONTEXT
结构。使用此CERT_CONTEXT
,我尝试了CertGetCertificateContextProperty
参数
CERT_KEY_CONTEXT_PROP_ID
CERT_KEY_PROV_HANDLE_PROP_ID
CERT_KEY_PROV_INFO_PROP_ID
CERT_HCRYPTPROV_OR_NCRYPT_KEY_HANDLE_PROP_ID
CERT_HCRYPTPROV_TRANSFER_PROP_ID
但是所有人都返回了CRYPT_E_NOT_FOUND
。我还试过GetCryptProvFromCert
希望获得证书容器句柄,这样我就可以通过CryptGetUserKey
获取密钥句柄了。但GetCryptProvFromCert
失败,错误为CRYPT_E_NO_KEY_PROPERTY
。
我目前正在使用纯CryptoAPI作为解决方法:CryptAcquireContext
来访问卡 - > CryptGetProvParam
枚举证书容器 - > CryptAcquireContext
访问容器 - > CryptGetUserKey
获得关键句柄。这远非理想,因为我通过容器进行交互以找到所需的证书。 gscBsiPkiGetCertificate
允许我指定AID值以直接获取证书。
我还尝试使用CryptEncryptMessage
直接使用PCCERT_CONTEXT
,因此无需使用HCRYPTKEY
。但是,尝试使用算法标识szOID_RSA
,szOID_RSA_ENCRPT
和szOID_RSA_DH
都会返回CRYPT_E_UNKNOWN_ALGO
。我非常确定该证书支持RSA加密,因为通过CryptoAPI获取的密钥句柄上使用CryptGetKeyParam
调用KP_ALGID
会返回CALG_RSA_KEYX
我正在使用BSI API访问卡内的数据和证书容器。我想避免解决方法,因为我想将所有智能卡操作标准化为仅使用BSI或CryptoAPI。如果我不可能使用BSI API获取密钥句柄,那么我想知道如何使用CryptoAPI来访问数据容器。 CryptGetProvParam
仅枚举证书容器。
答案 0 :(得分:0)
您可以尝试类似的方法
1)您获得证书上下文,例如
pSignerCertContext = CertFindCertificateInStore(hCertStore,PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,0,CERT_FIND_HASH,&hashBlob,NULL)
2)您可以获得加密提供者的句柄,例如:
CryptAcquireContext(&hProv,strContainer.c_str(),strProvider.c_str(),PROV_RSA_FULL,CRYPT_SILENT)
3)您将证书上下文与加密提供者相关联,例如
CertSetCertificateContextProperty(pSignerCertContext,CERT_SET_KEY_PROV_HANDLE_PROP_ID,0,&hProv)
4)之后,您可以使用CryptAcquireCertificatePrivateKey或CryptGetUserKey