如何获取 PCCERT_CONTEXT 的私钥的 NCRYPT_KEY_HANDLE?

Posted

技术标签:

【中文标题】如何获取 PCCERT_CONTEXT 的私钥的 NCRYPT_KEY_HANDLE?【英文标题】:How can I get a NCRYPT_KEY_HANDLE for the private key of a PCCERT_CONTEXT? 【发布时间】:2018-02-16 16:17:05 【问题描述】:

如何从 Windows 证书存储区中的 PCCERT_CONTEXT 的私钥中获取用于 CNG 加密/解密的 NCRYPT_KEY_HANDLE

CryptEncrypt 函数已被 NCryptEncryptBCryptEncrypt 函数取代,但没有直接明显的方法可以从 Windows 证书存储中的 PCCERT_CONTEXT 获取这两个函数的句柄。

是否甚至可以使用 CNG 功能使用证书(私钥)进行加密/解密,而无需解决像导出证书这样的暴力破解方法?

【问题讨论】:

【参考方案1】:

我自己回答这个问题,因为我在其他地方找不到答案:

以下代码将为您提供所需的内容:

const HCERTSTORE store(CertOpenStore(CERT_STORE_PROV_SYSTEM_W, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG, (const void*)L"MY"));
const PCCERT_CONTEXT certContext(CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_W, subjectName, nullptr));
if (certContext)

  HCRYPTPROV_OR_NCRYPT_KEY_HANDLE keyHandle;
  DWORD keySpec;
  BOOL callerFreesKeyHandle;

  // Get NCrypt key handle from certificate.
  // Might fail for instance if certificate private key is not accessible to current user.
  if (CryptAcquireCertificatePrivateKey(certContext, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, nullptr, &keyHandle, &keySpec, &callerFreesKeyHandle))
  
    check(keySpec == CERT_NCRYPT_KEY_SPEC); //< Should always have this value when giving CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG.
    UNIQUE_NCRYPT_KEY_HANDLE keyHandleKeeper;
    if (callerFreesKeyHandle)
    
      keyHandleKeeper.reset(keyHandle);
    
    ...

【讨论】:

感谢分享;我已将您的问题重新格式化为谢谢:)

以上是关于如何获取 PCCERT_CONTEXT 的私钥的 NCRYPT_KEY_HANDLE?的主要内容,如果未能解决你的问题,请参考以下文章

拥有一份 Apple 分发证书,但未安装其私钥。联系此证书的创建者以获取私钥的副本

各种格式SSH 公钥和私钥之间的转换

OpenSSH生成的私钥如何在putty中使用?

区块链学习钱包

RSA 非对称加解密 公私钥的生成

公钥跟私钥的理解