本控件只是个示例,功能比较简单,共有三个方法,本别是获取当前个人存储区证书列表、获取指定证书、使用指定证书签名。在Windows下使用Visual C++ 6.0开发ActiveX控件的步骤如下所示。

(1) 打开VC6,单击【File】|【New】命令,弹出【New】对话框。

(2)在【Projects】选项卡中,选择【MFC ActiveX ControlWizard】选项,创建一个ActiveX控件。在【Projectname】文本框中,输入项目名称“PKIAppControl”,如图所示。

(2)单击【OK】按钮,弹出ActiveX向导对话框,如图所示:

(3)使用默认设置,始终单击【Next】按钮,直到创建项目结束。为控件添加方法,如图所示:

添加GetUserList方法,无输入参数,返回值为BSTR。如图所示:

依次添加三个方法:

q      BSTR GetUserList();//获得证书列表

q      BSTR GetUserCert(BSTR sUserName);//根据证书名称获得对应证书(Base64编码)

q      BSTR SignData(BSTR sUserName, BSTR sDataToSign);//根据证书名称对数据签名,返回Base64编码的签名数据

三个函数的实现源码如下所示,主要是调用用第三篇涉及到的CryptoAPI函数。

/*获得系统个人存储区的签名证书列表

返回证书名称列表,格式为 CertName&&&CertName

如:郭靖&&&黄蓉&&&

*/

BSTR CPKIAppControlCtrl::GetUserList()

{

CString strResult="";

HCERTSTORE hCertStore;

PCCERT_CONTEXT pCertContext = NULL;

char pszNameString[256];

hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,

CERT_STORE_OPEN_EXISTING_FLAG |

CERT_SYSTEM_STORE_CURRENT_USER,

L"MY");

if(hCertStore == NULL)

{

return strResult.AllocSysString();

}

while(pCertContext= CertEnumCertificatesInStore(

hCertStore,

pCertContext))

{

CertGetNameString(pCertContext,CERT_NAME_SIMPLE_DISPLAY_TYPE,0,NULL,pszNameString,128);

strResult +=pszNameString;

strResult +="&&&";

}

CertCloseStore(hCertStore,0);

return strResult.AllocSysString();

}

//根据证书名称获得Base64编码的证书

BSTR CPKIAppControlCtrl::GetUserCert(LPCTSTR sUserName)

{

CString strResult="";

// TODO: Add your dispatch handler code here

CString strUserName = sUserName;

HCERTSTORE hCertStore;

PCCERT_CONTEXT pCertContext = NULL;

PCRYPT_KEY_PROV_INFO pKeyProvInfo=NULL;

hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,

CERT_STORE_OPEN_EXISTING_FLAG |

CERT_SYSTEM_STORE_CURRENT_USER, L"MY");

if(hCertStore == NULL)

{

return strResult.AllocSysString();

}

pCertContext=CertFindCertificateInStore(hCertStore,X509_ASN_ENCODING ,0,CERT_FIND_SUBJECT_STR,strUserName.AllocSysString(),NULL);

if(pCertContext==NULL)

{

return strResult.AllocSysString();

}

char * strCert=NULL;

DWORD dwCertLen;

CryptBinaryToString(pCertContext->pbCertEncoded,pCertContext->cbCertEncoded,CRYPT_STRING_BASE64,strCert,&dwCertLen);

strCert= (char *)malloc(dwCertLen+1);

CryptBinaryToString(pCertContext->pbCertEncoded,pCertContext->cbCertEncoded,CRYPT_STRING_BASE64,strCert,&dwCertLen);

strCert[dwCertLen]='/0';

strResult=strCert;

free(strCert);

free(pKeyProvInfo);

CertFreeCertificateContext(pCertContext);

CertCloseStore(hCertStore,0);

return strResult.AllocSysString();

}

//对数据进行签名,返回Base64编码的PKCS1格式的签名数据

BSTR CPKIAppControlCtrl::SignData(LPCTSTR sUserName, LPCTSTR sDataToSign)

{

CString strResult="";

// TODO: Add your dispatch handler code here

CString strUserName = sUserName;

CString strDataToSign = sDataToSign;

HCERTSTORE hCertStore;

PCCERT_CONTEXT pCertContext = NULL;

PCRYPT_KEY_PROV_INFO pKeyProvInfo=NULL;

DWORD dwLen;

hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,

CERT_STORE_OPEN_EXISTING_FLAG |

CERT_SYSTEM_STORE_CURRENT_USER, L"MY");

if(hCertStore == NULL)

{

return strResult.AllocSysString();

}

pCertContext=CertFindCertificateInStore(hCertStore,X509_ASN_ENCODING ,0,CERT_FIND_SUBJECT_STR,strUserName.AllocSysString(),NULL);

if(pCertContext==NULL)

{

CertCloseStore(hCertStore,0);

return strResult.AllocSysString();

}

if(!CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,pKeyProvInfo,&dwLen))

{

CertFreeCertificateContext(pCertContext);

CertCloseStore(hCertStore,0);

return strResult.AllocSysString();

}

pKeyProvInfo = (PCRYPT_KEY_PROV_INFO)malloc(dwLen);

if(!CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,pKeyProvInfo,&dwLen))

{

free(pKeyProvInfo);

CertFreeCertificateContext(pCertContext);

CertCloseStore(hCertStore,0);

return strResult.AllocSysString();

}

HCRYPTPROV hProv = 0;

CString sContainerName = pKeyProvInfo->pwszContainerName;

CString sProvName = pKeyProvInfo->pwszProvName;

if(!CryptAcquireContext(

&hProv,

sContainerName.GetBuffer(0),

sProvName.GetBuffer(0),

pKeyProvInfo->dwProvType,

0))

{

free(pKeyProvInfo);

CertFreeCertificateContext(pCertContext);

CertCloseStore(hCertStore,0);

return strResult.AllocSysString();

}

HCRYPTHASH hHash;

if(!CryptCreateHash(

hProv,

CALG_SHA1,

0,

0,

&hHash))

{

free(pKeyProvInfo);

CryptReleaseContext(hProv,0);

CertFreeCertificateContext(pCertContext);

CertCloseStore(hCertStore,0);

return strResult.AllocSysString();

}

if(!CryptHashData(

hHash,

(BYTE *)strDataToSign.GetBuffer(0),

strDataToSign.GetLength(),

0))

{

CryptDestroyHash(hHash);

free(pKeyProvInfo);

CryptReleaseContext(hProv,0);

CertFreeCertificateContext(pCertContext);

CertCloseStore(hCertStore,0);

return strResult.AllocSysString();

}

unsigned char Sign[256];

DWORD dwSignLen;

if(!CryptSignHash(

hHash,

pKeyProvInfo->dwKeySpec,

NULL,

0,

NULL,

&dwSignLen))

{

CryptDestroyHash(hHash);

free(pKeyProvInfo);

CryptReleaseContext(hProv,0);

CertFreeCertificateContext(pCertContext);

CertCloseStore(hCertStore,0);

return strResult.AllocSysString();

}

if(!CryptSignHash(

hHash,

pKeyProvInfo->dwKeySpec,

NULL,

0,

Sign,

&dwSignLen))

{

CryptDestroyHash(hHash);

free(pKeyProvInfo);

CryptReleaseContext(hProv,0);

CertFreeCertificateContext(pCertContext);

CertCloseStore(hCertStore,0);

return strResult.AllocSysString();

}

CryptDestroyHash(hHash);

free(pKeyProvInfo);

CryptReleaseContext(hProv,0);

CertFreeCertificateContext(pCertContext);

CertCloseStore(hCertStore,0);

char * strSign=NULL;

DWORD dwStrSignLen=0;

CryptBinaryToString(Sign,dwSignLen,CRYPT_STRING_BASE64,strSign,&dwStrSignLen);

strSign= (char *)malloc(dwStrSignLen+1);

CryptBinaryToString(Sign,dwSignLen,CRYPT_STRING_BASE64,strSign,&dwStrSignLen);

strSign[dwStrSignLen]='/0';

strResult=strSign;

free(strSign);

return strResult.AllocSysString();

}

该控件的工程源码请参考附属光盘,目录“Code/第五篇-电子商务网站应用/PKIAppControl”。

27.4.1 开发ActiveX控件相关推荐

  1. 使用C#开发ActiveX控件(新)

    前言 ActiveX控件以前也叫做OLE控件,它是微软IE支持的一种软件组件或对象,可以将其插入到Web页面中,实现在浏览器端执行动态程序功能,以增强浏览器端的动态处理能力.通常ActiveX控件都是 ...

  2. [转]C#开发ActiveX控件,.NET开发OCX控件案例

    引自:百度   http://hi.baidu.com/yanzuoguang/blog/item/fe11974edf52873aaec3ab42.html 讲下什么是ActiveX控件,到底有什么 ...

  3. 使用C#开发ActiveX控件[Obsolete]

    附件下载(源代码+安装文件+教程) 0. 前言 ActiveX控件以前也叫做OLE控件或OCX控件,它是一些软件组件或对象,可以将其插入到WEB网页或其它应用程序中.使用ActiveX插件,可以轻松方 ...

  4. [转]使用C#开发ActiveX控件

    前言 ActiveX控件以前也叫做OLE控件,它是微软IE支持的一种软件组件或对象,可以将其插入到Web页面中,实现在浏览器端执行动态程序功能,以增强浏览器端的动态处理能力.通常ActiveX控件都是 ...

  5. 使用C#开发ActiveX控件

    0. 前言 ActiveX控件以前也叫做OLE控件或OCX控件,它是一些软件组件或对象,可以将其插入到WEB网页或其它应用程序中.使用ActiveX插件,可以轻松方便的在 Web页中插入多媒体效果.交 ...

  6. (转)使用C#开发ActiveX控件

    本文转载自:http://www.cnblogs.com/yilin/archive/2009/09/15/1567332.html 附件下载(源代码+安装文件+教程) 0. 前言 ActiveX控件 ...

  7. 开发ActiveX控件调用另一个ActiveX系列0——身份证识别仪驱动的问题

    程序员要从0下表开始,这篇是介绍这个系列的背景的,没有兴趣的人可以直接跳过. 为什么要开发ActiveX控件 由于工作需要,我们开发了一个网站,使用了一款身份证识别仪的网页ActiveX(OCX)插件 ...

  8. [转]使用C#开发ActiveX控件全攻略

    先说说ActiveX的基本概念. 根据微软权威的软件开发指南MSDN(Microsoft Developer Network)的定义,ActiveX插件以前也叫做OLE控件或OCX控件,它是一些软件组 ...

  9. 使用C#开发ActiveX控件全攻略

    先说说ActiveX的基本概念. 根据微软权威的软件开发指南MSDN(Microsoft Developer Network)的定义,ActiveX插件以前也叫做OLE控件或OCX控件,它是一些软件组 ...

最新文章

  1. 基于SpringBoot的个人博客系统
  2. 基本表改变视图不改变为什么_中国白酒包装是真的很丑吗,为什么不改变包装?...
  3. 始于《将才》,而不止于将才
  4. 容器(一)剖析面试最常见问题之 Java 集合框架
  5. 【转】世上最简单的vue教程
  6. Docker中的Nginx搭建HTTPS环境
  7. 卸载frontpage服务器扩展_免费0撸一月腾讯云服务器
  8. Intellij IDEA 导入或运行流式处理框架storm以及java.lang.NoClassDefFoundError报错的解决方案
  9. seq2seq模型_用 CNN 实现 Seq2Seq 模型
  10. vue组件之间的数据共享
  11. SEO人员,如何搭建你的网站基础框架?
  12. c语言实现校园疫情防控系统
  13. JDBC SSL连接MySQL
  14. 创蓝253短信验证码接口接入常见问题
  15. 《快学Scala》第二章练习题答案+概述
  16. Android 开源项目分类汇总--1
  17. 人脑与计算机类比文献,类比推理的影响因素和脑生理基础研究(刘昌2004).pdf
  18. 计算机硬件的配置的图片,鲁大师怎么生成电脑配置图
  19. 安卓Native逆向之MOO音乐解密( .bkcflac,bkcmp3文件解密)
  20. ITE平台开发 chapter 1-环境搭建

热门文章

  1. 文本标注平台搭建之brat
  2. 韩流来袭,英文歌曲的垄断地位被撼动
  3. pycharm控制台打印彩色字体、python打印彩色字体
  4. robots机器人疾风 war_warrobots
  5. Mogafx欧美对有望上涨
  6. 随机森林原始论文_【20108】喜讯|刘倩同学论文被制冷学报期刊录用
  7. html 外部xml,如何在HTML中引用XML数据
  8. 线上python兼职推荐:500-800元/天!多做多得,时间自由!
  9. 与socket网络编程有关的函数
  10. 知识扩展----快速阅读