求 windows证书存储区提取问题

boreboluomi 2014-03-14 11:30:02
大家好。
我想得到windows存储区中“个人”中的所有PKCS12数据。我现在的问题是无法提取全部的PKCS12数据,只能提取出一个。

“个人”存储区中放置了多个可以提取私钥的证书,我想把他们以PKCS12格式都提取出来,使用了 cryptoAPI的PFXExportCertStoreEx()函数,但我通过它只能返回其中一个PKCS12数据流,经验值这个pkcs12数据是正确的。但无法得到里面的另外的那些密钥对儿。
希望朋友们告诉我能够得到全部pkcs12的方法。或者能够将里面的私钥以pkcs8格式遍历输出的方法。谢谢
...全文
307 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Samuel_yin 2015-07-13
  • 打赏
  • 举报
回复
楼主你好,我也在CryptoAPI的使用上遇到问题,我想请教下 FXPKI_ParseX509FromBuffer这函数要包含哪些类库?
boreboluomi 2014-03-17
  • 打赏
  • 举报
回复
谢谢赵老师。 我通过借助openssl达成了我的目标。 搞出两种方式,写出来给大家分享。 方式1: 1) HANDLE hStoreHandle = CertOpenSystemStore(0, "MY"); 2) PFXExportCertStoreEx(hStoreHandle, &PFX, L"111111", NULL, EXPORT_PRIVATE_KEYS); 3) FXPKI_ParsePKCS12FromBuffer(PFX.pbData, PFX.cbData, &pkcs12); 4) STACK_OF(PKCS7) asafes = PKCS12_unpack_authsafes((PKCS12 *)pkcs12)); 5) p7 = sk_PKCS7_value (asafes, i); 6) if (bagnid == NID_pkcs7_data) { bags = PKCS12_unpack_p7data(p7); } else if (bagnid == NID_pkcs7_encrypted) { bags = PKCS12_unpack_p7encdata(p7, pass, -1); } 7) PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value (bags, i); if (M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) continue; pkcs8 = PKCS12_decrypt_skey(bag, pass, passlen) ...) 得到与pkcs7匹配的私钥,类似方法也可获得公钥,时间原因,方法1我就简写到这里。 方式2: 1) HANDLE hStoreHandle = CertOpenSystemStore(0, "MY"); 2) pCertContext= CertEnumCertificatesInStore(hStoreHandle, pCertContext); 3) FXPKI_ParseX509FromBuffer(pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, &cert); 4) 伪IsCertMatched(cert, pkcs7); 5) CryptAcquireCertificatePrivateKey(pCertContext, 0, NULL, &hProv, &dwKeySpec, &fCallerFreeProv); 6) CryptGetUserKey(hProv, dwKeySpec, &hUserkey); 7) CryptExportKey(hUserkey, NULL, PRIVATEKEYBLOB, 0, pbKeyBlob, &dwDatalen); 8) EVP_PKEY *pkey = b2i_PrivateKey((const unsigned char **)&pbKeyBlob, dwDatalen); 如果使用openssl 这时已经可以用pkey做私钥可以做到事情了。如果想转换为pkcs8,那么: 1) BIO *bio = BIO_new(BIO_s_mem()); i2d_PKCS8PrivateKey_bio(bio, pkey, NULL, NULL, 0, NULL, NULL); EVP_PKEY_free(pkey); 2) int pkcs8Len = (FX_INT32)BIO_ctrl_pending(bio); 3) FX_BYTE *pkcs8 = FX_Alloc(FX_BYTE, pkcs8Len); BIO_read(bio, pkcs8, pkcs8Len); 以上我主要是为了列出主干接口,略掉了先得到buffer长度并动态分配后重新获取真正的数据步骤,还有略掉了重要的返回值判断与一些非主干接口调用,分享给大家仅供参考。
赵4老师 2014-03-14
  • 打赏
  • 举报
回复
如果私钥可以随便导出的话,就无法保证RSA的安全了。
boreboluomi 2014-03-14
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
引用 1 楼 zhao4zhong1 的回复:
有可能该私钥设置了限制,禁止Export。
谢谢!根据您的介绍,我已经知道自己哪里出了问题。我是不清楚pfx可以包含多套密钥。我原以为只包含一个。那么,下一个问题就是我如何在得到的pfx里遍历每一套密钥值了。这对我也是个问题,但本帖就此结贴。再次感谢
boreboluomi 2014-03-14
  • 打赏
  • 举报
回复
如果设置为私钥不可提取,那么在导出密钥过程中,那个“导出PKCS12”的选项变为不可选择,只可选择x509选项,也就是只可导出公钥。 很感谢您用这么多时间来照看我的帖子,并且对我的热心帮助!
boreboluomi 2014-03-14
  • 打赏
  • 举报
回复
换句话说,我现在不知道遍历 存储区中 pkcs12 的方法。csdn中对这个函数没有看到遍历 pkcs12的方法介绍。另外CryptExportPKCS8Ex()这个函数可以得到PKCS8 私钥值,但它只能用于一些特定的win系统,并代替的,还是用PFXExportCertStoreEx()函数,
赵4老师 2014-03-14
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
有可能该私钥设置了限制,禁止Export。
这只是我的一个猜想,仅供参考。 你可以试试 向里面导入两个不同的.pfx并设置为私钥不可以提取 ,然后试着在存储区管理器中手动提取它们的pkcs12格式文件,看看这两个是不是也无法正常提取
boreboluomi 2014-03-14
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
有可能该私钥设置了限制,禁止Export。
谢谢赵老师的帮助。我向里面导入了两个不同的.pfx并设置为私钥可以提取 ,然后试着在存储区管理器中手动提取pkcs12格式文件,这两个也都可以正常提取。 我通过PFXExportCertStoreEx()函数,得到“MY”存储区的CRYPT_DATA_BLOB结构,不过这里只包含了其中的一个pkcs12数据,没有包含另一个(另外,假如包含另一个,我不清楚它会如何包含,这个结构体只有两个成员:一个是数据指针,一个是指定数据长度。 是不是PFXExportCertStoreEx这个函数无法得到全部的PKCS12?)。
赵4老师 2014-03-14
  • 打赏
  • 举报
回复
有可能该私钥设置了限制,禁止Export。

3,882

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧