27.4.1 开发ActiveX控件
本控件只是个示例,功能比较简单,共有三个方法,本别是获取当前个人存储区证书列表、获取指定证书、使用指定证书签名。在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控件相关推荐
- 使用C#开发ActiveX控件(新)
前言 ActiveX控件以前也叫做OLE控件,它是微软IE支持的一种软件组件或对象,可以将其插入到Web页面中,实现在浏览器端执行动态程序功能,以增强浏览器端的动态处理能力.通常ActiveX控件都是 ...
- [转]C#开发ActiveX控件,.NET开发OCX控件案例
引自:百度 http://hi.baidu.com/yanzuoguang/blog/item/fe11974edf52873aaec3ab42.html 讲下什么是ActiveX控件,到底有什么 ...
- 使用C#开发ActiveX控件[Obsolete]
附件下载(源代码+安装文件+教程) 0. 前言 ActiveX控件以前也叫做OLE控件或OCX控件,它是一些软件组件或对象,可以将其插入到WEB网页或其它应用程序中.使用ActiveX插件,可以轻松方 ...
- [转]使用C#开发ActiveX控件
前言 ActiveX控件以前也叫做OLE控件,它是微软IE支持的一种软件组件或对象,可以将其插入到Web页面中,实现在浏览器端执行动态程序功能,以增强浏览器端的动态处理能力.通常ActiveX控件都是 ...
- 使用C#开发ActiveX控件
0. 前言 ActiveX控件以前也叫做OLE控件或OCX控件,它是一些软件组件或对象,可以将其插入到WEB网页或其它应用程序中.使用ActiveX插件,可以轻松方便的在 Web页中插入多媒体效果.交 ...
- (转)使用C#开发ActiveX控件
本文转载自:http://www.cnblogs.com/yilin/archive/2009/09/15/1567332.html 附件下载(源代码+安装文件+教程) 0. 前言 ActiveX控件 ...
- 开发ActiveX控件调用另一个ActiveX系列0——身份证识别仪驱动的问题
程序员要从0下表开始,这篇是介绍这个系列的背景的,没有兴趣的人可以直接跳过. 为什么要开发ActiveX控件 由于工作需要,我们开发了一个网站,使用了一款身份证识别仪的网页ActiveX(OCX)插件 ...
- [转]使用C#开发ActiveX控件全攻略
先说说ActiveX的基本概念. 根据微软权威的软件开发指南MSDN(Microsoft Developer Network)的定义,ActiveX插件以前也叫做OLE控件或OCX控件,它是一些软件组 ...
- 使用C#开发ActiveX控件全攻略
先说说ActiveX的基本概念. 根据微软权威的软件开发指南MSDN(Microsoft Developer Network)的定义,ActiveX插件以前也叫做OLE控件或OCX控件,它是一些软件组 ...
最新文章
- 基于SpringBoot的个人博客系统
- 基本表改变视图不改变为什么_中国白酒包装是真的很丑吗,为什么不改变包装?...
- 始于《将才》,而不止于将才
- 容器(一)剖析面试最常见问题之 Java 集合框架
- 【转】世上最简单的vue教程
- Docker中的Nginx搭建HTTPS环境
- 卸载frontpage服务器扩展_免费0撸一月腾讯云服务器
- Intellij IDEA 导入或运行流式处理框架storm以及java.lang.NoClassDefFoundError报错的解决方案
- seq2seq模型_用 CNN 实现 Seq2Seq 模型
- vue组件之间的数据共享
- SEO人员,如何搭建你的网站基础框架?
- c语言实现校园疫情防控系统
- JDBC SSL连接MySQL
- 创蓝253短信验证码接口接入常见问题
- 《快学Scala》第二章练习题答案+概述
- Android 开源项目分类汇总--1
- 人脑与计算机类比文献,类比推理的影响因素和脑生理基础研究(刘昌2004).pdf
- 计算机硬件的配置的图片,鲁大师怎么生成电脑配置图
- 安卓Native逆向之MOO音乐解密( .bkcflac,bkcmp3文件解密)
- ITE平台开发 chapter 1-环境搭建