前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >解析P12证书

解析P12证书

作者头像
全栈程序员站长
发布2022-09-07 11:30:20
7820
发布2022-09-07 11:30:20
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。1.从磁盘上的证书文件中读取证书数据 unsigned char* pbP12Data; // 证书数据 unsigned long ulP12DataLen; // 证书数据长度

2.让用户输入证书密码 char* szPwd; // 证书密码

3.将证书密码转换成UNICODE格式(最好采用二次调用方式) LPWSTR pWideChar = NULL; int nWideChar = 0; nWideChar = MultiByteToWideChar(CP_ACP, 0, szPwd, -1, pWideChar, nWideChar); pWideChar = new WCHAR[nWideChar]; memset(pWideChar, 0, sizeof(WCHAR)*nWideChar); MultiByteToWideChar(CP_ACP, 0, szPwd, -1, pWideChar, nWideChar);

4.将证书数据导入临时store CRYPT_DATA_BLOB blob; memset(&blob, 0, sizeof(blob)); blob.pbData = pbP12Data; blob.cbData = ulP12DataLen; HCERTSTORE hCertStore = NULL; hCertStore = PFXImportCertStore(&blob, pWideChar, CRYPT_EXPORTABLE);

5.在store中查找证书,获取CertContext PCCERT_CONTEXT pCertContext = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL);

6.获取证书信息 CRYPT_INTEGER_BLOB snBlob = pCertContext->pCertInfo->SerialNumber; // 证书SN pCertContext->pbCertEncoded; // X509格式证书数据 pCertContext->cbCertEncoded; // X509格式证书数据长度

7.获取CSP句柄 HCRYPTPROV hProv = NULL; DWORD dwKeySpec = 0; BOOL bCallerFreeProv = FALSE; CryptAcquireCertificatePrivateKey(pCertContext, 0, NULL, &hProv, &dwKeySpec, &bCallerFreeProv);

8.获取密钥句柄 HCRYPTKEY hKey = NULL; CryptGetUserKey(hProv, dwKeySpec, &hKey);

9.导出私钥(最好采用二次调用方式) BYTE* pbData = NULL; DWORD dwDataLen = 0; CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbData, &dwDataLen); pbData = new BYTE[dwDataLen]; memset(pbData, 0, dwDataLen); CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbData, &dwDataLen);

10.获取公私钥信息 BYTE *p = pbData+ sizeof(PUBLICKEYSTRUC); (*(RSAPUBKEY*)p).bitlen; // 公私钥模长(以bit为单位) (*(RSAPUBKEY*)p).pubexp; // 公钥的e(注意字节顺序) p += sizeof(RSAPUBKEY); // 公私钥的n(注意字节顺序) p += ((*(RSAPUBKEY*)p).bitlen)/8; // 私钥的p(注意字节顺序) p += ((*(RSAPUBKEY*)p).bitlen)/16; // 私钥的q(注意字节顺序) p += ((*(RSAPUBKEY*)p).bitlen)/16; // 私钥的dp(注意字节顺序) p += ((*(RSAPUBKEY*)p).bitlen)/16; // 私钥的dq(注意字节顺序) p += ((*(RSAPUBKEY*)p).bitlen)/16; // 私钥的qu(注意字节顺序) p += ((*(RSAPUBKEY*)p).bitlen)/16; // 私钥的d(注意字节顺序)

11.清理工作 delete[] pbData; pbData = NULL; CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); CertFreeCertificateContext(pCertContext); CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); delete[] pWideChar; pWideChar = NULL;

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/148171.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档