前两周,公司的某销售经理和另一个公司某高管一起拍脑袋提出来一个需求。这不是最尴尬的,最尴尬的是这群人一直没搞懂到底要实现个什么东西。
需求不明确不说,要点资料客户还藏着掖着不给,tnn的,我不由得怀疑,项目经理除了把问题变得更复杂外还有个jb用?最后这群爷好不容易弄清楚
要做一个csp插件。
==================================背景分割线===============================
吐槽到此结束,咱们说正题,就是这个csp(crypt service provider,, 加密服务提供者)。这是微软大哥给我们留出来的一个可自定义的插件,当然接口要按照规范来写。这个东西的资料啊我就不多说了,丢给各位一个地址csp。
我做的呢是基于智能卡的一个csp,这个东西可坑苦哥了,首先你要明白csp里面的基础机制(默认大家都看过介绍了)。
咱先不研究这玩意怎么写,先研究这玩意怎么用的。
这里面有几个比较重要的注册表键:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider
这个根键就是用来记录加密服务提供者的, CryptEnumProviders 遍历的就是它的子项,我们添加和删除一个provider就操作这个键。
每一个provider都有以下几个基本子键:
Image Path:插件保存的路径
SigInFile:签名文件 (On NT5, CSP images can carry their own signatures,也就是xp以上的系统都可以自己携带签名证书了,在远古版本里面,数字证书也要写在注册表里面,现在基本都写0);
Type:服务类型
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards
这个根键是用来记录用于加密服务的智能卡,智能卡的名称作为子项名,我们在这个下面添加自定义服务的硬件部分。
80000001:用于卡片与系统交流的模块
Crypto Provider: 所属的加密服务提供者,要一致
Smart Card Key Store Provider: key存储提供者
后两个项很好理解,这个80000001我也有些疑惑,我打开系统中自带的模块,发现里面只有一个函数。
上函数:
DWORD WINAPI CardAcquireContext(
__in PCARD_DATA pCardData,
__in DWORD dwFlags
);
微软大哥的解释是这样的:
The CardAcquireContext function, defined by a smart card module, initializes communication between the smart card module and either the Microsoft Base Smart Card Cryptographic Service Provider (CSP) or smart card key storage provider (KSP).
这个模块是用来微软和卡片交流用的,微软与智能卡打交道我知道的有两种方式:
第一种就是直接怼,通过SCardConnect建立和读卡器的链接,然后通过SCardTransmit 与智能进行数据交流;
第二种就是通过一些标准的APi,比如说CardReadFile,CardAcquireContext之类的,那这些API由谁来实现?当然是卡片提供商;
这个80000001项存储的就是智能卡操作标准api的实现模块。
那有人说这个东西是必须的吗?我说未必,因为你可以实现这些个接口,然后系统可以调用,csp也可以调用,这是一举两得,你要是嫌弃麻烦也可以直接在csp里面实现,这都没毛病。
目前我涉及到的就是这两个键了。
以下代码来自微软cspdk,但是这玩意太tnn古老了,所以用的时候要修改一下。
:头文件
#include "stdafx.h"
#include "wincrypt.h""
#include <winscard.h>
#include <tchar.h>
#include "cspdk.h"
:重要变量
static HMODULE
GetInstanceHandle(
void);
#ifdef SCARD_CSP
//智能卡的名字
static const TCHAR
l_szCardName[]
= TEXT("?vendor? <Add your Smart Card Friendly Name Here>");
//私人提供者的guid
static const GUID // Optional
l_guidPrimaryProv
//?vendor? Add your Primary Provider GUID here
= { /* 00000000-0000-0000-0000-000000000000 */
0x00000000,
0x0000,
0x0000,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
//智能卡ATR
static const BYTE
l_rgbATR[] = { /* ?vendor? Add your ATR here */ 0x3b, 0x00 },
l_rgbATRMask[] = { /* ?vendor? Add your ATR Mask here */ 0xff, 0xff };
#endif
//csp服务提供者的名字
static const TCHAR
l_szProviderName[]
= TEXT("?vendor? <Add your Provider Name Here>");
//服务类型
static const DWORD
l_dwCspType
// ?vendor? Change this to match your CSP capabilities
= PROV_RSA_FULL;
typedef DWORD
(*LPSETCARDTYPEPROVIDERNAME)(
IN SCARDCONTEXT hContext,
IN LPCTSTR szCardName,
IN DWORD dwProviderId,
IN LPCTSTR szProvider);
:卸载服务
/*++
DllUnregisterServer:
This service removes the registry entries associated with this CSP.
Arguments:
None
Return Value:
Status code as an HRESULT.
Author:
Doug Barlow (dbarlow) 3/11/1998
--*/
STDAPI
DllUnregisterServer(
void)
{
LONG nStatus;
DWORD dwDisp;
HRESULT hReturnStatus = NO_ERROR;
HKEY hProviders = NULL;
SCARDCONTEXT hCtx = NULL;
//
// Delete the Registry key for this CSP.
//HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider
//这是加密服务提供者的注册表根键
//
nStatus = RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider"),
0,
TEXT(""),
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hProviders,
&dwDisp);
if (ERROR_SUCCESS == nStatus)
{
RegDeleteKey(hProviders, l_szProviderName);
Re