CA服务器开开发(三)---UsbKey认证 客户端Activex Com组件

PCI/CA体系下使用USBkey实现认证与加密(一)整体架构 USB Key也叫做USB Token,是一种USB接口的硬件设备, 网银的“U盾”就是USB key的一种。USBkey中存储有用户的私钥以及数字证书,并且可执行生成公私钥对,硬件数字签名的等运算。USB Key主要用于实现网络认证,其结合物理实体和PIN双因子认证得方式,相当比较安全,主要用于网上银行或要求较高的企业远程办公用户。本文简单对USPkey实现认证加密的整体流程进行描述,希望对需要建设企业USBkey认证业务的读者有所帮助。 阅读详情

使用Activex主要为了嵌入网页和服务端C#来调用加密。这里只给出关键代码吧

1.私钥解密

STDMETHODIMP CMAddr::DePrivKey(BSTR encode, BSTR* orign)
{

	//HCERTSTORE  hCertStore = NULL;
	BOOL ret=TRUE;
	HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv =NULL;
	BOOL bFreeKeyProv=FALSE;
	DWORD dwKeyType;
	HCRYPTKEY hKey = NULL;
	BYTE* pTempByte=NULL;
	CString outStr;
	CString run;

	run="DecodeJson";
	CString b64Str(encode);
	CString tempStr;
	CStringDecodeBase64(b64Str,tempStr);
	Json::Reader reader;
	Json::Value root;  

	if(NULL==Current_PCTX)
	{
		MessageBox("请选择证书!");
		goto cleanup;
	}

	if (!reader.parse(tempStr.GetBuffer(), root))
	{
		goto cleanup;
	}

	DWORD dwCount=root.size();
	pTempByte=new BYTE[dwCount];
	for(DWORD i=0;i<dwCount;i++)
	{
		pTempByte[i]=root[i].asInt();
	}
	
	run="CryptAcquireCertificatePrivateKey";
	ret=CryptAcquireCertificatePrivateKey(Current_PCTX, 0, 0, &hCryptProv, &dwKeyType, &bFreeKeyProv);
	if(!ret)goto cleanup;

	run="CryptGetUserKey";
	ret=CryptGetUserKey(hCryptProv,AT_KEYEXCHANGE,&hKey);
	if(!ret)goto cleanup;

	run="CryptDecrypt";
	ret=CryptDecrypt(hKey, 0, true, 0,pTempByte, &dwCount);
	if(!ret)goto cleanup;

	for(DWORD i=0;i<dwCount;i++)
	{
		outStr.AppendChar(pTempByte[i]);
	}

cleanup:
	if(NULL!=pTempByte)
	{
		delete[] pTempByte;
		pTempByte=NULL;
	}

	if(NULL!=hKey)
	{
		CryptDestroyKey(hKey);
	}

	if(NULL!=hCryptProv&&bFreeKeyProv)
	{
		CryptReleaseContext(hCryptProv,0);
	}

	if(!ret)
	{
		outStr.Empty();
		outStr.Format("ErrorCode:%0x"+run, GetLastError());
	}
	CComBSTR tempSTR(outStr);
	tempSTR.CopyTo(orign);
	tempSTR.Empty();
	return S_OK;
}

2.公钥加密

STDMETHODIMP CMAddr::EnPubKey(BSTR orign, BSTR cert, BSTR* encode)
{
	PCCERT_CONTEXT pCertContext=NULL;
	HCERTSTORE hCertStore = NULL;    
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTKEY hPubKey = NULL;
	BYTE* pBinByte=NULL;
	BYTE* pOrignByte=NULL;

	BOOL ret;
	DWORD binBytes = 0;
	CString outStr;
	CString run;
	CString tempStr;
	Json::Value value;

	//get cert
	std::wstring scert(cert,SysStringLen(cert));

	run="Acquire Context";
	ret=CryptAcquireContext(&hCryptProv,NULL, NULL,PROV_RSA_FULL,0);
	if(!ret)goto cleanup;

	run="Read Cert";
	ret=CryptStringToBinaryW(scert.c_str()  , scert.length() ,CRYPT_STRING_BASE64HEADER , NULL , &binBytes ,NULL,NULL);
	if(!ret)goto cleanup;

	pBinByte=new BYTE[binBytes];
	ZeroMemory(pBinByte,binBytes);
	ret=CryptStringToBinaryW(scert.c_str() , scert.length() ,CRYPT_STRING_BASE64HEADER , pBinByte, &binBytes ,NULL,NULL);
	if(!ret)goto cleanup;

	run="Create Cert";
	pCertContext = CertCreateCertificateContext( PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, pBinByte , binBytes );

	run="Import PubKey";
	ret=CryptImportPublicKeyInfo(hCryptProv,PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
		&(pCertContext->pCertInfo->SubjectPublicKeyInfo),
		&hPubKey);
	if(!ret)goto cleanup;

	DWORD orignLen=SysStringLen(orign);
	DWORD pDataLen=orignLen;


	run="Run Encrypt";
	ret=CryptEncrypt(hPubKey,NULL,true,0,NULL,&pDataLen,orignLen);
	if(!ret)goto cleanup;

	pOrignByte=new BYTE[pDataLen];
	ZeroMemory(pOrignByte,pDataLen);

	for(DWORD i=0;i<orignLen;i++)
	{
		pOrignByte[i]=(BYTE)orign[i];
	}

	ret=CryptEncrypt(hPubKey,NULL,true,0,pOrignByte,&orignLen,pDataLen);
	if(!ret)goto cleanup;

	for(DWORD i=0;i<pDataLen;i++)
	{
		value[i]=pOrignByte[i];
	}
	tempStr=value.toStyledString().c_str();
	CStringEncodeBase64(tempStr,outStr);

cleanup:
	if(NULL!=pOrignByte)
	{
		delete[] pOrignByte;
		pOrignByte=NULL;
	}

	if(NULL!=pBinByte)
	{
		delete[] pBinByte;
		pBinByte=NULL;
	}

	if(NULL!=pCertContext)
	{
		CertFreeCertificateContext(pCertContext);
	}

	if(NULL!=hPubKey)
	{
		CryptDestroyKey(hPubKey);
	}


	if(NULL!=hCryptProv)
	{
		CryptReleaseContext(hCryptProv,0);
	}

	if(!ret)
	{
		outStr.Empty();
		outStr.Format(run+"ErrorCode:%0x", GetLastError());
	}


	CComBSTR outStrTemp(outStr);
	outStrTemp.CopyTo(encode);
	outStrTemp.Empty();
	return S_OK;
}

为了避免登录的时候重复选择证书,用户选择证书使用静态变量保存,并手动释放

STDMETHODIMP CMAddr::LoadCert(BSTR* certInfo)
{
	//加载会话证书
	
	HCERTSTORE       hCertStore = NULL;
	CString resultStr="";
	CString subject = "";
	CString sno="";
	Json::Value value;
	CHAR szName[1024];

	hCertStore = CertOpenSystemStore(
		0,
		"MY");
	if(NULL == hCertStore)
	{
		CertCloseStore(hCertStore, 0);
		MessageBox("CertOpenSystemStore Error!");
		goto cleanup;
	}
	Current_PCTX = CryptUIDlgSelectCertificateFromStore(
		hCertStore,   
		NULL,NULL,NULL,
		CRYPTUI_SELECT_LOCATION_COLUMN,0,NULL);

	if(!Current_PCTX)
	{
		MessageBox("请选择证书!");
		goto cleanup;
	}
	 ZeroMemory(szName,1024);
	 CertNameToStr(Current_PCTX->dwCertEncodingType,
		 &Current_PCTX->pCertInfo->Subject,
		 CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
		 szName,
		 sizeof(szName));
	 subject.Append(szName);

	 for(DWORD i=0 ;i<Current_PCTX->pCertInfo->SerialNumber.cbData; i++)
	 {
	 	BYTE  byteTemp =Current_PCTX->pCertInfo->SerialNumber.pbData[i];
	 	byteTemp = (byteTemp&0xF0>>4)|(byteTemp&0x0F<<4);
	 	sno.Format("%X"+sno,byteTemp);
	 }
	 
	 value["name"]=Json::Value(sno);
	 value["subject"]=Json::Value(subject);

	 resultStr.Append(value.toStyledString().c_str());
cleanup:
	CComBSTR tempSTR(resultStr);
	tempSTR.CopyTo(certInfo);
	tempSTR.Empty();
	if(NULL!=hCertStore)
	{
		CertCloseStore(hCertStore,NULL);
	}
	return S_OK;
}


STDMETHODIMP CMAddr::FreeCert(void)
{
	//释放会话证书
	if(NULL!=Current_PCTX)
	{
		CertFreeCertificateContext(Current_PCTX);
		Current_PCTX=NULL;
	}
	return S_OK;
}

这样一个完整的CA服务器开发的核心部分已经介绍完了。加密解密方法并没有做中文编码的处理,由于原文中也不含有中文,所以我也没处理。




基于activex的usbkey网络身份认证 NULL 博文链接:https://fengxingshenzhou.iteye.com/blog/755750 立即下载

相关推荐

通过nodejs 调用 海泰方圆的usbkey 接口

通过nodejs 调用 海泰方圆的usbkey 接口,需要完整代码和我联系40744069@qq.com

学习CRYPTO第三天

1,CertOpenSystemStore打开系统最常用的证书存储区域。假如需要满足复杂的需要,请看CertOpenStore HCERTSTORE WINAPI CertOpenSystemStore( HCRYPTPROV hprov, //CSP句柄,NULL为默认句柄,或者由CryptAcquireContext返回 LPTCSTR szSubsystemProtocol //打开的...

yujiawei的专栏 287

手把手教你制作ActiveX控件

手把手教你制作ActiveX控件

签名证书和加密证书的区别

一般来说CA的USBKEY会有双证书,一个签名,一个加密 签名: 防伪造,防抵赖 加密:防偷窥 签名:私钥签名,公钥验证,所以就算私钥遗失了,以前签名的数据仍然有效,所以私钥一般只有一份 加密:公钥加密,私钥解密,一旦私钥遗失,则数据就无法还原了,所以CA一般会备份加密证书 加密证书也可用于签名,但签名证书不可用于加密 以上,其他二者几乎没有区别 转载于:...

weixin_34210740的博客 3450

Camera mipi通信协议

MIPI(移动行业处理器接口),是的缩写。MIPI移动行业处理器接口)是MIPI联盟发起的为移动应用处理器制定的开放标准。分别定义了一系列的手机内部接口标准,比如摄像头接口CSI、显示接口DSI,其中是由MIPI联盟下Camera工作组指定的接口标准。CSI-2是MIPI CSI第二版,主要由应用层、协议层、物理层组成,最大支持4通道数据传输、单线传输速度高达1Gb/s。

arvin_xiong的博客 3730

ROS新手必看:5分钟搞定URDF小车建模(附Rviz可视化调试技巧)

本文为ROS新手提供了快速构建URDF机器人模型的实战指南。通过一个完整的两轮差速小车建模案例,详细解析了URDF的核心语法、Rviz可视化调试技巧以及常见问题排查方法,帮助初学者快速掌握ROS机器人建模与可视化调试的核心技能。

weixin_29079643的博客 247

枚举证书和 CAPI读取证书总结

枚举证书 以下几点介绍下面的示例代码的关键部分。 调用以获取句柄 CertOpenSystemStore 函数 uint hCertStore = Crypt32.CertOpenSystemStore(0, "My"); 用户的个人证书存储区。 调用 CertEnumCertificatesInStore 函数,以获取证书上下文指针到 while (0

wdt3385的专栏 6801

学Simulink--基于电力电子变换器的建模与仿真实例:LLC谐振变换器在高频AC-DC转换中的建模

本文详细介绍了使用Simulink+Simscape Electrical对LLC谐振变换器进行建模与仿真的完整流程。LLC谐振变换器因其高效率、低噪声的特点,广泛应用于高频AC-DC转换场景。文章从背景原理出发,逐步讲解系统结构设计、建模步骤(包括AC源、整流器、LLC变换器、负载等模块搭建)、控制策略实现(固定频率/变频/PID控制)和仿真设置。通过分析仿真结果的关键指标,提出参数整定和算法优化建议。该建模方法为电力电子设计人员提供了实用的仿真工具,有助于优化LLC变换器性能,缩短开发周期。

xiaoheshang_123的博客 296

PKI证书认证

<br />USBKEY介绍<br />usbkey的本质就是一个移动存储设备+硬件加密算法实现。自身有一定的安全性。需要登录后才能访问相应权限的文件。其权限分为 anyone(任何人都可见)、pin(需要输入pin码,才可见)、admin(只有管理员可见。)相应的admin可以看见所有信息。pin看不见admin的信息。anyone只能看见一些普通信息。所以pin码是决定账号能否访问Ukey的标志。<br />每一个Ukey中都有一个GUID。确保唯一。<br />注:对于1000系统来说,忘记管理员密码

ti_tans的专栏 2189

innovus中如何设置cts参数

上面是设置cts的一般设置,如果需要对某些skew group或者某些clock tree设置不一样的参数,如需要对clk1这个clock设置不一样的inverter,可以使用。需要查询已经设置过的ccopt参数,可以使用get_ccopt_property去查询,方法和set_ccopt_property一致。言归正传,cts的设置命令是set_ccopt_property,获取命令是get_ccopt_property。另外,set_ccopt_property提供一套命令查询方法。

芯冰乐 543

基于Solidworks的三维光路结构示意图绘制实例演示-技术细节

基于Solidworks的三维光路结构示意图绘制实例演示-技术细节

简单光学 1万+

对接湖南CA使用U_KEY登录

ca、使用usbKey登录

qq_44275894的博客 3855

Qt垂直滚动条QVerticalScrollBar详解:从基础到实战的控件开发指南

本文系统解析Qt中QVerticalScrollBar的用法,从基础概念到进阶技巧。主要内容包括:1)基础认知:介绍其继承关系、作用及典型应用场景;2)核心用法:创建方法、关键属性配置和信号槽连接;3)进阶技巧:自定义样式表美化外观,以及与自定义内容区域的联动实现;4)实战注意事项,如避免循环触发和高DPI适配等。文章强调掌握QVerticalScrollBar对提升Qt滚动类功能开发效率的重要性,并建议通过自定义文本编辑器实践巩固知识点。

专注现代C++实战,从核心语法到高性能编程,助力开发者深入掌握系统级编程精髓。 757

一个解析PE文件的小工具(可以检测一些可疑的api)

文章目录 // 003_解析导入表.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include &lt;windows.h&gt; DWORD RvaToOffset( IMAGE_NT_HEADERS* pNtHdr , DWORD dwRva ) { // 1. 找Rva所在的区段 // 2. 用Rva减去所在区段的首Rva ,再用减...

richard1230的博客 1003

学Simulink——基于扩展卡尔曼滤波(EKF)的列车牵引电机转子温度在线估计仿真

本文介绍了一种基于扩展卡尔曼滤波(EKF)的列车牵引电机转子温度在线估计方法,通过Simulink建模实现。文章首先阐述了EKF在估计电机转子温度中的优势,即利用易测量信号(如电流、电压、转速)在线估计难以直接测量的转子温度,并分析了温升对电机性能的影响。随后详细讲解了电机热电增广模型的构建,包括定子电阻温度关系、一阶热近似模型和PMSM的dq轴方程。接着,文章提供了Simulink建模的详细步骤,包括PMSM+FOC电流环的搭建、EKF算法的实现(推荐使用ExtendedKalmanFilter块或MAT

xiaoheshang_123的博客 54

【服务器电源架构与关键技术发展趋势】AI数据中心迅猛发展,服务器电源如何演变?

功率级跃升:机柜功率从 100kW 向 1MW 级发展,供电架构采用 HVDC + 固态变压器(SST),省去传统 UPS、PFC 环节; 母线电压升级:从 48V 向 400V→800V 演进,配套 AI 电弧检测、智能运维解决高压安全与维护难题; 能效(PUE)提升:目标 PUE<1.3,通过液冷 CDU 替代传统风冷,可将 PUE 降至 1.16(传统 AI 集群 PUE 达 1.6); 拓扑控制复杂化:功率拓扑从单相→三相、单级→多交错结构,适配高功率需求; 安全维度扩展:新增网络安全防护需求。

昔时扬尘处 1449

根据USB 序列号 生成USB Key

在软件安装的时候,常常要验证软件的有效性,这时候发行产品的时候会附带一个USB Key,主程序运行的时候检查这个Key的合法性,如果通过验证,那么启动主程序。下面的代码提供了实现该方法的途径:///     /// USB 操作相关    ///     public class UsbUtility    {        const string Key_File_Name = "Usb.ke

深蓝的智慧,医生的严谨 3604

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

COM组件基本概念

com组件模型

zqlnuclear的博客 1293

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

解决吉大正源(身份认证网关|USBKey)和gmssl(server|client)使用gmtl协议交叉互通报错tlsv1 alert decrypt error

解决吉大正源(身份认证网关|USBKey)和gmssl(server|client)使用gmtl协议交叉互通报错SSL_connect:error in SSLv3/TLS write finished 140057291788288:error:1409441B:SSL routines:ssl3_read_bytes:tlsv1 alert decrypt error:ssl/record/rec_layer_s3.c:1385:SSL alert number 51

CHYabc123456hh的博客 2827

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

gmssl服务端和客户端程序、吉大正元身份认证网关、吉大正元SDK+USBkey 两两之间双证书双向认证数据通信测试

gmssl服务端和客户端程序、吉大正元身份认证网关、吉大正元SDK+USBkey 两两之间数据通信测试

CHYabc123456hh的博客 1万+

CA服务器开开发(二)---UsbKey认证 服务端

认证过程为,服务端生成一个随机数(认证原文),CA服务器中使用用户的证书里面的公钥进行加密这个随机数,然后用户收到这个加密后的随机数后使用usbkey里面的私钥来解密出认证原文,然后将原文发送到服务端进行比对,如果和开始生成的原文一致,则用户的身份是合法的。 这里我写了一个WebService来生成原文并保存到数据库。然后通过插件来提取用户证书公钥加密。 public class CALo

xugangjava的专栏 7052

证书函数

http://weng851217.blog.163.com/blog/static/884996120110205622778/ // ============================ 证书管理 // 获取证书名称 void viewCertCN(PCCERT_CONTEXT hCert) {     TCHAR sName[1024];     DWORD

wdt3385的专栏 1730

封装好的CAPI证书函数

http://weng851217.blog.163.com/blog/static/884996120110205622778/ // ============================ 证书管理 // 获取证书名称 void viewCertCN(PCCERT_CONTEXT hCert) {    TCHAR sName[1024];    DWORD nNameSiz

wdt3385的专栏 1314

C#创建一个PKCS#10(p10)的证书请求文件

CX509PrivateKey pkey=new CX509PrivateKeyClass();             CX509CertificateRequestPkcs10 req=new CX509CertificateRequestPkcs10Class();             try             {                 var template

对信仰的忠诚丶 6640

读取数字签名方法

#ifndef UNICODE #define UNICODE #endif #ifndef _UNICODE #define _UNICODE #endif #define _WIN32_WINNT 0x0500 #define WINVER 0x0500 #include <windows.h> #include <Softpub...

weixin_30267691的博客 594
上一篇: CA服务器开开发(二)---UsbKey认证 服务端
下一篇: 清空Activti脚本
xugangjava
博客等级 码龄16年 83粉丝 72原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值