Windows证书函数

2023-05-16


C语言操作WINDOWS系统存储区数字证书相关函数详解及实例
 以下代码使用C++实现遍历存储区证书及使用UI选择一个证书  
 --使用 CertOpenSystemStore打开证书存储区. 
 --在循环中,使用CertEnumCertificatesInStore. 枚举所有存储区中的证书. 
 --使用CryptUIDlgViewContext显示一个证书 . 
 --使用CertGetNameString取得证书主题名称. 
 --在循环中,使用 CertEnumCertificateContextProperties 获取与证书关联的所有属性标识. 
 --使用CertGetCertificateContextProperty 获取每一个标识值. 
 --使用CryptUIDlgSelectCertificateFromStore以UI的方式列出存储区所有证书并提示用户选择其中一个. 
 --使用 CertCloseStore关闭存储区. 

 函数详解 
 1.CertOpenSystemStore 

 HCERTSTORE WINAPI CertOpenSystemStore( 
 __in HCRYPTPROV_LEGACY hprov,//CSP句柄,一般设置为NULL 
 __in LPTCSTR szSubsystemProtocol//有四种类型,CA:认证机构证书;MY:关联私钥的证书存储区;ROOT:根证书;SPC:Software Publisher Certificate. 
 ); 
 如果成功此函数函数一个证书存储区的句柄,否则返回NULL,证书存储区被打开后所有标准证书存储函数均可使用,使用完毕后请用CertCloseStore关闭存储区 
 2.CertEnumCertificatesInStore 

 PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore( 
 __in HCERTSTORE hCertStore, 
 __in PCCERT_CONTEXT pPrevCertContext 
 ); 
 hCertStore:存储区句柄 
 pPrevCertContext:指向先前创立的证书上下文CERT_CONTEXT 结构体,这个参数必须先置为NULL才能获取第一个证书 
 3.CryptUIDlgViewContext 
 列出一个证书,CTL或CRL上下文 
 BOOL WINAPI CryptUIDlgViewContext( 
 __in DWORD dwContextType, 
 __in const void pvContext, 
 __in HWND hwnd, 
 __in LPCWSTR pwszTitle, 
 __in DWORD dwFlags, 
 __in void pvReserved 
 ); 
 dwContextType :上下文的类型,如下表 
 Value/Meaning 
 CERT_STORE_CERTIFICATE_CONTEXT/PCCERT_CONTEXT 

 CERT_STORE_CRL_CONTEXT/PCCRL_CONTEXT 

 CERT_STORE_CTL_CONTEXT/PCCTL_CONTEXT 
 pvContext :指向列出的证书,CTL或CRL上下文的指针 
 hwnd :窗口显示句柄 
 pwszTitle :显示标题字符串 
 dwFlags :一般设置为0 
 pvReserved :保留 
 4.CertGetNameString 
 从一个证书的CERT_CONTEXT 结构体中取得主题或颁发者名称 
 DWORD WINAPI CertGetNameString( 
 __in   PCCERT_CONTEXT pCertContext, 
 __in   DWORD dwType, 
 __in   DWORD dwFlags, 
 __in   void pvTypePara, 
 __out LPTSTR pszNameString, 
 __in   DWORD cchNameString 
 ); 
 dwType :名称的输出格式 
 CERT_NAME_EMAIL_TYPE:如果证书有主题可选名称扩展或颁发者名称,使用rfc822Name 选项. 如果在扩展里没有发现 rfc822Name 选项,使用该Email OID的主题名 

 称域 . 如果rfc822Name或the Email OID 均没发现, 使用string. 否则返回空值 (returned character count is 1). pvTypePara 不使用,设置为 NULL. 
 CERT_NAME_RDN_TYPE:调用CertNameToStr转换主题名称BLOB . pvTypePara points to a DWORD containing the dwStrType passed to CertNameToStr. 如果主 

 题名称域为空且证书拥有一个主题可选扩展使用来自CertNameToStr的第一个目录名称 
 CERT_NAME_ATTR_TYPE:例如,如果pvTypePara 值为szOID_COMMON_NAME,使用主题名称成员,如果主题名称成员为空且证书拥有一个可选名称扩展,使用第一个目录名称选项 
 CERT_NAME_SIMPLE_DISPLAY_TYPE:使用下列顺序szOID_COMMON_NAME, szOID_ORGANIZATIONAL_UNIT_NAME, szOID_ORGANIZATION_NAME, or szOID_RSA_emailAddr如果其中一个属性没有找到,使用主题可选名称扩展,如果这些都不匹配则使用第一个属性 
 CERT_NAME_FRIENDLY_DISPLAY_TYPE 
 CERT_NAME_DNS_TYPE 
 CERT_NAME_URL_TYPE 
 CERT_NAME_UPN_TYPE 
 5.CertEnumCertificateContextProperties 
 DWORD WINAPI CertEnumCertificateContextProperties( 
 __in PCCERT_CONTEXT pCertContext, 
 __in DWORD dwPropId//取得第一个属性该值设为0,取得接下来的属性该值为此函数所返回 
 ); 
 6.CertGetCertificateContextProperty 
 BOOL WINAPI CertGetCertificateContextProperty( 
 __in   PCCERT_CONTEXT pCertContext, 
 __in   DWORD dwPropId, 
 __out   void pvData, 
 __inout DWORD pcbData 
 ); 
 该获取证书属性信息,详细请参考http://msdn.microsoft.com/en-us/library/aa376079(VS.85).aspx 

 7.CryptUIDlgSelectCertificateFromStore 
 PCCERT_CONTEXT WINAPI CryptUIDlgSelectCertificateFromStore( 
 __in     HCERTSTORE hCertStore, 
 __in     HWND hwnd, 
 __in_opt LPCWSTR pwszTitle, 
 __in_opt LPCWSTR pwszDisplayString, 
 __in     DWORD dwDontUseColumn, 
 __in     DWORD dwFlags, 
 __in     void pvReserved 
 ); 
 弹出一个对话框,允许用户从指定存储目录中选择一个证书 

 代码[综合]:VC++6下面调试成功 

 #i nclude <stdio.h> 
 #i nclude <windows.h> 
 #i nclude <wincrypt.h> 
 #i nclude <cryptuiapi.h>//需要装PLATFORM SDK 
 #i nclude <tchar.h> 
 #pragma comment (lib, "crypt32.lib") 
 #pragma comment (lib, "cryptui.lib") 
 #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) 
 void MyHandleError(char s); 
 void main(void) 
 { 

 
 HCERTSTORE     hCertStore;     
 PCCERT_CONTEXT   pCertContext=NULL;   
 char pszNameString[256] ; 
 char pszStoreName[256] = "MY"; 

 DWORD         dwPropId = 0; 
 char thumb[100]=""; 
 char temstring[10]; 
 pCertContext = NULL; 
 if ( hCertStore = CertOpenSystemStore( 
   NULL, 
   pszStoreName)) 
 { 
   fprintf(stderr,"The s store has been opened. \n", pszStoreName); 
 } 
 else 
 { 
   MyHandleError("The store was not opened."); 
 } 

 //使用CertEnumCertificatesInStore从存储区获取证书,pCertContext必须置为NULL才能找到第一个证书 

 while(pCertContext= CertEnumCertificatesInStore( 
   hCertStore, 
   pCertContext)) 
 { 
 //打印证书名称 
 if(CertGetNameString( 
   pCertContext, 
   CERT_NAME_RDN_TYPE, 
   0, 
   NULL, 
   pszNameString, 
   128)) 
   printf("\nCertificate for s \n",pszNameString); 
 //遍历指定证书所有属性标识 
 while(dwPropId = CertEnumCertificateContextProperties( 
     pCertContext, // 所列出的证书属性的上下文 
     dwPropId))   // dwPropId值必须先置为0 
 { 

 
 //循环开始执行,属性值被找到 
 printf("Property # d found->", dwPropId); 

 //------------------------------------------------------------------- 
 // Indicate the kind of property found. 

   switch(dwPropId) 
   { 
   case CERT_FRIENDLY_NAME_PROP_ID: 
   { 
     printf("Display name: "); 
     break; 
   } 
   case CERT_SIGNATURE_HASH_PROP_ID: 
   { 
     printf("Signature hash identifier "); 
     break; 
   } 
   case CERT_KEY_PROV_HANDLE_PROP_ID: 
   { 
     printf("KEY PROVE HANDLE"); 
     break; 
   } 
   case CERT_KEY_PROV_INFO_PROP_ID: 
   { 
     printf("KEY PROV INFO PROP ID "); 
     break; 
   } 
   case CERT_SHA1_HASH_PROP_ID: 
   { 
     printf("SHA1 HASH identifier"); 
     break; 
   } 
   case CERT_MD5_HASH_PROP_ID: 
   { 
     printf("md5 hash identifier "); 
     break; 
   } 
   case CERT_KEY_CONTEXT_PROP_ID: 
   { 
     printf("KEY CONTEXT PROP identifier"); 
     break; 
   } 
   case CERT_KEY_SPEC_PROP_ID: 
   { 
     printf("KEY SPEC PROP identifier"); 
     break; 
     } 
     case CERT_ENHKEY_USAGE_PROP_ID: 
     { 
     printf("ENHKEY USAGE PROP identifier"); 
     break; 
     } 
     case CERT_NEXT_UPDATE_LOCATION_PROP_ID: 
     { 
     printf("NEXT UPDATE LOCATION PROP identifier"); 
     break; 
     } 
     case CERT_PVK_FILE_PROP_ID: 
     { 
       printf("PVK FILE PROP identifier "); 
       break; 
     } 
     case CERT_DESCRIPTION_PROP_ID: 
     { 
     printf("DESCRIPTION PROP identifier "); 
     break; 
     } 
     case CERT_ACCESS_STATE_PROP_ID: 
     { 
     printf("ACCESS STATE PROP identifier "); 
     break; 
     } 
     case CERT_SMART_CARD_DATA_PROP_ID: 
     { 
       printf("SMART_CARD DATA PROP identifier "); 
       break; 
     } 
     case CERT_EFS_PROP_ID: 
     { 
     printf("EFS PROP identifier "); 
     break; 
     } 
     case CERT_FORTEZZA_DATA_PROP_ID: 
     { 
     printf("FORTEZZA DATA PROP identifier "); 
     break; 
     } 
     case CERT_ARCHIVED_PROP_ID: 
     { 
     printf("ARCHIVED PROP identifier "); 
     break; 
     } 
     case CERT_KEY_IDENTIFIER_PROP_ID: 
     { 
     printf("KEY IDENTIFIER PROP identifier "); 
     break; 
     } 
     case CERT_AUTO_ENROLL_PROP_ID: 
     { 
     printf("AUTO ENROLL identifier. "); 
     break; 
     } 

 
   } // End switch. 
 printf("\n"); 

 
 } // End inner while. 
 } // End outer while. 

 //------------------------------------------------------------------- 
 // Select a new certificate by using the user interface. 
 //使用UI选择一个新证书 
 if(!(pCertContext = CryptUIDlgSelectCertificateFromStore( 
 hCertStore, 
 NULL, 
 NULL, 
 NULL, 
 CRYPTUI_SELECT_LOCATION_COLUMN, 
 0, 
 NULL))) 
 { 
   MyHandleError("Select UI failed." ); 
 } 
 else 
 { 
 //显示名称 

 if(CertGetNameString( 
   pCertContext, 
   CERT_NAME_RDN_TYPE, 
   0, 
   NULL, 
   pszNameString, 
   128)) 
 { 
   printf("\nCertificate for s \n",pszNameString); 

 
 LPBYTE pEncodedBytes = NULL; 
 LPBYTE pHash; 
 DWORD cbData, i; 
 pHash = NULL; 
 cbData = 0; 

 CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, NULL, &cbData); 
 if (cbData == 0) 
 { 
   MyHandleError("CertGetCertificateContextProperty 1 failed"); 
 } 
 pHash = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, cbData); 
 if (pHash == NULL) 
 { 
   MyHandleError("HeapAlloc failed"); 
 } 
 if (!CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, pHash,                         &cbData)) 
 { 
   MyHandleError("CertGetCertificateContextProperty 2 failed"); 
 } 

 printf("CERT_HASH_PROP_ID Length is d\n", cbData); 

 
 for (i = 0; i < cbData; i++) 
 { 
    
 sprintf( temstring,"02x",   pHash); 
 strcat(thumb,temstring); 
 } 

 printf("The thumb is s", thumb); 

 } 
 else 
   fprintf(stderr,"CertGetName failed. \n"); 
 } 

 //------------------------------------------------------------------- 
 // Clean up. 

 CertFreeCertificateContext(pCertContext); 
 CertCloseStore(hCertStore,0); 

 } // End of main. 

 
 void MyHandleError(LPTSTR psz) 
 { 
   _ftprintf(stderr, TEXT("An error occurred in the program. \n")); 
   _ftprintf(stderr, TEXT("s\n"), psz); 
   _ftprintf(stderr, TEXT("Error number x.\n"), GetLastError()); 
   _ftprintf(stderr, TEXT("Program terminating. \n")); 
   exit(1); 
 } // End of MyHandleError.  

 

转载于:https://www.cnblogs.com/Dennis-mi/articles/3336287.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows证书函数 的相关文章

  • 当我启动程序时,Arduino IDE (Win10) 崩溃

    我的 Arduino IDE Win10 上的版本为 1 8 12 在启动时崩溃 运行arduino debug exe我收到此错误消息 C Program Files x86 Arduino gt arduino debug exe Se
  • 安装 confluence-kafka 时“文件名或扩展名太长”?

    我在使用 pip install confluence kafka 安装 confluence kafka 时遇到一些问题 但我收到此错误 文件名或扩展名太长 详细信息如下 Collecting confluent kafka Using
  • 识别 Windows 版本

    我正在编写一个打印出详细 Windows 版本信息的函数 输出可能是这样的元组 32bit XP Professional SP3 English 它将支持 Windows XP 及更高版本 我一直坚持获取 Windows 版本 例如 专业
  • Python 原始字符串和尾随反斜杠[重复]

    这个问题在这里已经有答案了 我曾经遇到过一些东西 想知道它是否是一个 Python bug 或者至少是一个错误功能 我很好奇是否有人知道这种行为的任何理由 我刚刚在阅读 Code Like a Pythonista 时想到了这一点 到目前为
  • 读取进程的进程内存不会返回所有内容

    我正在尝试扫描第三方应用程序的内存 我已经查到地址了 现在是在0x0643FB78 问题是 从那以后我就再也爬不上去LPMODULEENTRY32 gt modBaseAddr is 0x00400000 and LPMODULEENTRY
  • 更改Word文档中的文本字体颜色

    我写了一个小测试词插件 但找不到方法改变字体颜色一句话 这是我的代码 var wordsList this Application ActiveDocument Words wordsList i Font TextColor WdColo
  • 在 Windows 中使用 OpenAI API 密钥时出现问题

    我必须在自定义数据集上微调 OpenAI 模型 我已经创建了 jsonl 格式的数据集 我在 Windows 命令行上使用以下命令 set OPENAI API KEY
  • 如何安装适用于 Windows C++ 的最新版本 OpenGL?

    我正在使用 Visual Studio 2010 运行 Windows 7 包含的 OpenGL 版本 include 是版本 1 1 我希望使用合理的当前版本 某种版本 3 或 4 我需要做什么才能达到该状态 OpenGL SDK 页面位
  • 如何使用 wamp 在 Windows 上烘焙 cakephp 2.0 应用程序

    我想在Windows系统上烤蛋糕php项目 我正在使用 wamp 服务器来运行 PHP mysql 我已经浏览过 cakephp 网站上的视频投射 并设置了环境设置 按照演示给出命令 蛋糕 后 最后我收到一条消息说 php 不被识别为内部或
  • 类似于eternity的C++对象持久化库

    我正在寻找一个 C 对象持久库来替换永恒图书馆 http sourceforge net projects eternity it 我已经用它制作了大约一天的原型 永恒图书馆的能力不足 我创建了一个与此类似的对象层次结构 我有一个std l
  • Windows 注册表中的 DefaultConnectionSettings 值的格式是什么?

    Windows 注册表项 HKCU Software Microsoft Windows CurrentVersion Internet Settings Connections 包含一个名为的二进制值DefaultConnectionSe
  • 批处理:在特定程序中打开特定文件?

    当记事本是 txt 文件的默认程序时 如何告诉 Windows 在写字板中打开 C test test txt 接受的答案对我不起作用 我不确定这是因为我试图运行的程序 还是因为路径中有空格 即使我用引号引起来 或者其他原因 不管怎样 我可
  • Scala 和 Spark:Windows 上的 Dataframe.write._

    有人设法使用 Spark 写入文件 尤其是 CSV 吗 数据框 http spark apache org docs latest api scala index html org apache spark sql Dataset在 Win
  • 当工作站锁定然后解锁时,如何防止窗口大小调整?

    我们有一个在多显示器环境中运行的应用程序 用户通常将应用程序对话框分散到多个监视器上 如果用户锁定工作站 然后解锁它 我们的应用程序就会被告知调整大小 我们的用户发现这种行为令人沮丧 因为他们随后花了一些时间恢复以前的布局 我们还不确定是图
  • npm 安装旧版本的(typescript 编译器)包

    在Windows环境下 我有 节点 v4 6 0 npm v3 10 8 我的本地打字稿版本是 npm run tsc v 3 10 8 但是 我有时想使用我的全局 tsc 因为出于某种原因 gulp 使用全局 tsc 但是当我这样做时 n
  • 如何用C语言测量时间?

    我想知道某个代码块执行了多长时间 大约 像这样的事情 startStopwatch do some calculations stopStopwatch printf lf timeMesuredInSeconds How 您可以使用clo
  • Inno Setup 安装可以设置 Windows 安全组吗?

    如何在 Inno Setup 安装过程中设置 Windows 安全组 我似乎想不出正确的文本来谷歌来弄清楚 也许暗示要搜索什么就足够了 好的 我找到了一些东西 我可以使用 net localgroup Windows 命令 http tec
  • 如果防火墙打开,Java 7 会阻止 Windows Vista 和 7 上的 FTP 传输。有任何想法吗?

    Java 7 阻止 Windows Vista 和 7 上的 FTP 传输 在 FTP 中 在传输文件之前 必须发送 PORT 或 PASV 命令 一旦发送其中一个命令 Windows 防火墙就会关闭发送该命令的套接字 仅当防火墙打开并且
  • 枚举nodejs中的系统驱动器

    有没有办法检索计算机上所有逻辑驱动器的驱动器名称 我查看了 fs api 但从那里我只能枚举给定目录的文件和目录 我不确定 驱动器名称 是什么意思 如果您的意思是以下形式的驱动器 PhysicalDriveN 我遇到了同样的问题并实现了这个
  • 需要帮助通过批处理文件添加注册表项

    我正在尝试通过cmd添加以下注册表项 我无法让其他用户能够使用以下命令添加此注册表项regedit exe s Location Project reg HKEY CURRENT USER Software Autodesk Fabrica

随机推荐

  • 链表头结点的作用

    1 防止单链表是空的而设的 当链表为空的时候 带头结点的头指针就指向头结点 如果当链表为空的时候 单链表没有带头结点 那么它的头指针就为NULL 2 是为了方便单链表的特殊操作 插入在表头或者删除第一个结点 这样就保持了单链表操作的统一性
  • Shikra的PID调参教程

    在论坛里看到的Shikra的PID调参教程 xff0c 自己感觉非常好就转过来供大家一起交流学习 http www rcgroups com forums showthread php t 61 1375728 还有师兄的调PID的整理的文
  • 四旋翼位置控制之-定高篇

    先mark一下 xff0c 争取两周之内写完 由于快要毕业了 xff0c 所以一直都很忙 xff0c 并没有时间写完 xff0c 所以拖到现在 xff0c 不好意思 现在开始介绍四旋翼定高以及调试过程 首先介绍下四旋翼的模型 图中为 四旋翼
  • 四元数、欧拉角和方向余弦的定义及关系

    目前 xff0c 描述两个坐标系之间关系的常用方法主要有欧拉角法 方向余弦矩阵法和四元数法 因此要弄懂这三种方法的定义及关系 xff0c 我们必须先从坐标系转化开始了解 下面以四旋翼为例 xff0c 定义两个坐标系 导航坐标系 参考坐标系
  • 四旋翼姿态解算常用的两种算法-互补滤波和梯度下降算法

    上一篇讲了四元数 欧拉角和方向余弦的知识 xff0c 不熟悉的请到这篇博客查看点击打开链接 介绍两种算法前 xff0c 先定义两个坐标系 导航坐标系 参考坐标系 n xff0c 选取东北天右手直角坐标系作为导航坐标系n 载体坐标系 机体坐标
  • 四旋翼位置控制之-GPS水平位置控制

    mark一下 xff0c 争取一周内抽时间写完 感兴趣的朋友可以加我qq讨论 最近事情太多 xff0c 今天争取写完 先给大家介绍一些基本知识 GPS精度因子 xff1a PDOP xff08 Position Dilution of Pr
  • 基于四元数的扩展卡尔曼(EKF)滤波器四旋翼姿态解算详解-1.KF介绍

    先说明一下 xff0c 之前介绍的两种姿态解算算法http blog csdn net wkdwl article details 52119163 互补滤波和入梯度下降姿态解算算法 xff0c 虽然在姿态解算方面效果还比较不错 但是缺点就
  • android开发(一)常见问题

    1 android开发环境 1 添加环境变量名称为 xff1a ANDROID HOME ANDROID HOME 61 D xxx android android sdk 2 下面路径添加到path环境变量里 ANDROID HOME p
  • 基于四元数的扩展卡尔曼(EKF)滤波器四旋翼姿态解算详解-2.EKF介绍

    尽快抽时间写完吧
  • Linux环境安装RabbitMQ

    RabbitMQ Linux环境安装 检查当前linux服务器的版本 lsb release a 官网下载安装包 xff1a https www rabbitmq com download html 1 2 3 选择对应的安装环境 4 对照
  • MySQL的安装

    MySQL的安装 1 下载 网址 xff1a https dev mysql com downloads mysql 2 下载5 7版本 xff08 1 xff09 xff08 2 xff09 xff08 3 xff09 3 配置环境变量
  • Nginx windows server 2012部署过程

    部署静态网页到服务器 今天做了一个静态网页 xff0c 想部署带到自己的阿里云服务器 通过查询可以使用tomcat容器或者nginx xff0c 主流方式是nginx部署 xff0c 记录一下自己部署的过程 一 nginx简介 Nginx
  • 点击按钮实时刷新图片

    js给 lt img gt 标签的src赋值 最近做一个点击一个按钮刷新加载另一张图片的功能 主要就是改变图的路径 记录一下自己遇到的坑 支持原生的js和jq实现 用js原生方法 xff1a document getElementById
  • RestTemplate的学习与使用

    RestTemplate的学习与使用 最近在开发过程中遇到使用接口传输数据 了解到到RestTemplate 1 源码分析 span class token keyword public span span class token keyw
  • Linux环境下redis的安装

    Linux环境下redis的安装 1 下载redis安装包 服务器上执行以下命令下载redis安装包 cd export software wegt http download redis io releases redis 6 2 6 t
  • Docker的安装

    Docker的安装 1 linux下安装docker xff08 CentOS7 xff09 curl sSL https get daocloud io docker sh 2 查看docker的版本 docker v 3 启动 关闭do
  • Redis的应用场景

    1 String操作 xff08 1 xff09 计数器 incr artcle readconunt 文章id get artcle readconunt 文章id 2 Hash操作 1 对象缓存 hmset user 1 name li
  • nginx在linux环境安装

    1 安装依赖包 yum install pcre pcre devel y yum install openssl openssl devel y 2 官网下载安装包传到linux环境 安装包存放位置 export software 解压目
  • 开发杂谈(一)常见问题

    1 github 1 从GITHUB下载慢而且容易中断解决办法 1 从GITHUB下载慢而且容易中断解决办法 将github项目导入到码云网 xff08 https gitee com xff09 然后再下载会很快 xff0c 登录码云网后
  • Windows证书函数

    C语言操作WINDOWS系统存储区数字证书相关函数详解及实例 以下代码使用C 43 43 实现遍历存储区证书及使用UI选择一个证书 使用 CertOpenSystemStore打开证书存储区 在循环中 使用CertEnumCertifica