实验一-Password engine-加密API研究
GMT 0016-2012
typedef struct Struct_DEVINFO{ VERSION Version; CHAR Manufacturer[64]; CHAR Issuer[64]; CHAR Label[32]; CHAR SerialNumber[32]; VERSION HWVersion; VERSION FirmwareVersion; ULONG AlgSymCap; ULONG AlgAsymCap; ULONG AlgHashCap; ULONG DevAuthAlgld; ULONG TotalSpace; ULONG FreeSpace; ULONG MaxECCBufferSize; ULONG MaxBufferSize; BYTE Reserved[64]; }DEVINFO,PDEVINFO;
使用方式举例
1、等待设备插拔事件
函数原型 | ULONG DEVAPI SKF_WaitForDevEvent(LPSTR szDevName,ULONG pulDevNameLen,ULONG pulEvent) |
---|---|
功能描述 | 该函数等待设备插入或者拔除事件。szDevName返回发生事件的设备名称。 |
参数 | szDevNarme 【OUT】发生事件的设备名称。 |
pulDevNameLen 【IN/OUT】输入/输出参数,当输入时表示缓冲区长度,输出时表示设备名称的有效长度,长度包含字符串结束符。 | |
pulEvent 【OUT】事件类型。1表示插入,2 表示拔出。 | |
返回值 | SAR_OK: 成功。 |
其他∶ 错误码 |
2、取消等待设备插拔事件
函数原型 | ULONG DEVAPI SKF_CancelWaitForDevEvent() |
---|---|
功能描能 | 该函数取消等待设备插入或者拔除事件 |
参数返回值 | SAR_OK: 成功。 |
其他∶ 错误码 | |
使本进程正在执行的 SKF_WaitForDevEvent 函数立即返回。 |
3、连接设备
函数原型 | ULONG DEVAPI SKF_ConnectDev(LPSTR szName,DEVHANDLE*phDev) |
---|---|
功能描述 | 通过设备名称连接设备,返回设备的句柄。 |
参数 | zName 【IN】 设备名称。 |
phDev 【OUT】返回没备操作句柄。 | |
返回值 | SAR_OK: 成功。 |
其他∶ 错误码 |
4、 断开连接
函数原型 | ULONG DEVAPI SKF_DisConnectDev(DEVHANDLE hDev) |
---|---|
功能描述 | 断开一个已经连接的设备,并释放句柄。 |
参数 | hDev 【IN】连接设备时返回的设备句柄。 |
返回值 | SAR_OK: 成功。 |
其他∶ 错误码 | |
如果该设备已被锁定,函数应首先解锁该设备。断开连接操作并不影响设备的权限状态 |
GMT 0018-2012
实际数据结构定义
typedef struct Devicelnfo_st{ unsigned char IssuerName[40]; unsigned char DeviceName[16]; unsigned char DeviceSerial[16]; unsigned int DeviceVersion; unsigned int StandardVersion; unsigned int AsymAlgAbility[2]; unsigned int SymAlgAbility; unsigned int HashAlgAbility; unsigned int BufferSize;)DEVICEINFO; }
使用方式举例
1、打开设备
函数原型 | int SDF_OpenDevice(void ** phDeviceHandle); |
---|---|
功能描述 | 打开密码设备。 |
参数 | phDeviceHandle【OUT】返回设备句柄 |
返回值 | 0: 成功。 |
其他∶ 失败,返回错误代码 |
2、关闭设备
函数原型 | int SDF_CloseDevice(void *hDeviceHandle); |
---|---|
功能描述 | 关闭密码设备,并释放相关资源。 |
参数 | hDeviceHandle 【in】已打开的设备句柄 |
返回值 | 0: 成功。 |
其他∶ 失败,返回错误代码 |
3、获取设备信息
函数原型 | int SDF_GetDevicelnfo( void * hSessonHandle, DEVICEINFO* pstDevicelnfo); |
---|---|
功能描述 | 获取密码设备能力描述。 |
参数 | hSessionHandle【in】与设备建立的会话句柄 |
pstDevceInfo【OUT】设备能力描述信息,内容及格式见设备信息定义 | |
返回值 | 0: 成功。 |
其他∶ 失败,返回错误代码 |
4、产生随机数
函数原型 | int SDF_GenerateRandom (void * hSessionHandle, unsigned int uilength, unsigned char * pucRandom); |
---|---|
功能描述 | 获取指定长度的随机数。 |
参数 | hSessionHandle【in】与设备建立的会话句柄 |
pucRandom【OUT】缓冲区指针,用于存放获取的随机数 | |
uiLength【in】欲获取的随机数长度 | |
返回值 | 0: 成功。 |
其他∶ 失败,返回错误代码 |
Crypto API
使用方式举例
1.CertOpenSystemStore打开系统最常用的证书存储区域。
HCERTSTORE WINAPI CertOpenSystemStore(
HCRYPTPROV hprov, //CSP句柄,NULL为默认句柄,或者由CryptAcquireContext返回
LPTCSTR szSubsystemProtocol //打开的系统存储区的名字。假如名字不为CA,MY,ROOT,SPC则新建一个证书存储区域,可以使用CertEnumSystemStore列出所有的已存在的系统存储区
);
2.CertOpenStore使用一个指定的存储区提供类型来打开一个证书存储区。
HCERTSTORE WINAPI CertOpenStore(
LPCSTR lpszStoreProvider, //指定提供的存储的类型,大量类型,请参见MSDN
DWORD dwMsgAndCertEncodingType, //只有当上一参数为CERT_STORE_PROV_MSG, CERT_STORE_PROV_PKCS7, or CERT_STORE_PROV_FILENAME才使用,否则必须为0
HCRYPTPROV hCryptProv, //密码算法提供方的句柄,推荐使用默认,将参数置为NULL
DWORD dwFlags, //它由高字节和低字节组成,参数众多。
const void* pvPara //void类型,可以指向任意类型数据。
);
例如:if(hSysStore = CertpenStore(CERT_STORE_PROV_SYSTEM,0,NULL,CERT_SYSTEM_STORE_CURRENT_USER,L"MY")打开系统的MY存储区
3.CertCloseStore
BOOL WINAPI CertCloseStore(
HCERTSTORE hCertStore, //证书存储区句柄
DWORD dwFlags
);
第二个参数一般为0,关闭了存储区,但是里面内容并没有释放
假如为CERT_CLOSE_STORE_CHECK_FLAG,检查没有释放空间的证书,CRL和CTL内容。他将返回一个错误报告。一般只用用于程序的诊断工具。
假如为CERT_CLOSE_STORE_FORCE_FLAG,则强制释放相关空间。他只在存储区打开并且存储区以及其相关内容没有被别的程序调用的时候使用才安全的。
4.CertDuplicateStore复制存储区,其reference count 也将增一,返回一个存储区的句柄
HCERTSTORE WINAPI CertDuplicateStore( HCERTSTORE hCertStore );
PKCS#11
结构定义:
CK_TOKEN_INFO provides informationabout a token. It is defined as follows:
typedef struct CK_TOKEN_INFO {
CK_UTF8CHAR label [32];
CK_UTF8CHAR manufacturerID[32];
CK_UTF8CHAR model [16];
CK_CHAR serialNumber[16];
CK_FLAGS flags;
CK_ULONG ulMaxSessionCount;
CK_ULONG ulSessionCount;
CK_ULONG ulMaxRwSessionCount;
CK_ULONG ulRwSessionCount;
CK_ULONG ulMaxPinLen;
CK_ULONG ulMinPinLen; CK_ULONG ulTotalPublicMemory;
CK_ULONG ulFreePublicMemory;
CK_ULONG ulTotalPrivateMemory;
CK ULONG ulFreePrivateMemory;
CK_VERSION hardwareVersion;
CK_VERSION firmwareVersion;
CK_CHAR utcTime [16];
)CK_TOKEN_INFO;
二、API所包含的函数
Crypto API
基本加密函数包含了以下几种∶
服务提供者函数:
应用程序使用服务提供者函数来连接和断开一个CSP。下面就是主要的API∶
CryptAcquireContext | 获得指定 CSP 的密钥容器的句柄 |
---|---|
CrypContextAddRef | 对 HCRYPTPROV 句柄增加一个应用计数 |
CrypEnumProviders | 枚举当前计算机中的 CSP |
CryptEnumProviderTypes | 枚举 CSP的类型 |
CSP CrypGetDefaultProvider | 对于指定 CSP 类型的却省 |
CryptGetProvParam | 得到一个 CSP 的属性 |
CryptIntallDefaultContext | 安装先前得到的 HCRYPTPROV 上下文作为当前却省的上下文 |
CryptReleaseContext | 释放由 CryptAcquireContext 得到的句柄 |
CryptSetProvider</br>CryptSetProviderEx | 为指定 CSP类型指定一个却省的 CSP |
CryptSetProvParam | 指定一个 CSP的属性 |
CryptUninstallDefaultContext | 删除先前由CryptInstallDefaultContext 安装的却省上下文 |
密钥的产生和交换函数:
CryptAcquireCertificatePrivateKey | 对于指定证书上下文得到一个 HCRYPTPROV 句柄和dwKeySpec |
---|---|
CryptDeriveKey | 从一个密码中派生一个密钥 |
CryptDestoryKey | 销毁密钥 |
CryptDuplicateKey | 制作一个密钥和密钥状态的精确复制 |
CryptExportKey | 把 CSP的密钥做成 BLOB 传送到应用程序的内存空间中 |
CrypGenKey | 创建一个随机密钥 |
CryptGenRandom | 产生一个随机数 |
CryptGetKeyParam | 得到密钥的参数 |
CryptGetUserKey | 得到一个密钥交换或签名密钥的句柄 |
编码/解码函数
有一些编码/解码函数,他们可以用来对证书、证书撤销列表、证书请求和证书扩展进行编码和解码。
以下就是这几个函数∶
CrypDecodeObject | 对 lpszStructType 结构进行解码 |
---|---|
CryptDecodeObjectEx | 对 lpszStructType 结构进行解码,此函数支持内存分配选项 |
CryptEncodeObject | 对 lpszStructType 结构进行编码 |
CyptEncodeObjectEx | 对 lpszStructType 结构进行编码,此函数支持内存分配选项 |
数据加密/解密函数
这些函数支持数据的加密/解密操作。CryptEncrypt 和CryptDecrypt 要求在被调用前指定一个密钥。这个密钥可以由 CryptGenKey、CryptDeriveKey 或CryptlmportKey产生。创建密钥时要指定加密算法。CryptSetKeyParam 函数可以指定额外的加密参数。
CrypDecrypt | 使用指定加密密钥来解密一段密文 |
---|---|
CryptEnerypt | 使用指定加密密钥来加密一段明文 |
CryptProtectData | 执行对 DATA_BLOB 结构的加密 |
CyptUnprotetData | 执行对 DATA_BLOB 结构的完整性验证和解密 |
GMT 0016-2012
设备管理系列函数:
等待设备插拔事件 | SKF_WaiForDevEvent |
---|---|
取消等待设备插拔事件 | SKF_CancelWaitForDevEvent |
枚举设备 | SKF_EnumDev |
连接设备 | SKF_ConnetDev |
断开连接 | SKF_DiscomnetDev |
获取设备状态 | SKF_GeDevState SKF_SetLabel |
设置设备标签获取设备信息 | SKF_GetDevinfo |
锁定设备 | SKF_LockDev |
解锁设备 | SKF_UnlockDev |
设备命令传输 | SKF_Transmit |
访问控制类系列函数:
函数名称 | 功 能 |
---|---|
SKF_ChangeDevAutKey | 修改设备认证 |
SKF_DevAuth | 密钥设备认证 |
SKF_ChangePIN | 修改 PIN |
SKF_GetPINInfo | 获得 PIN 码信息 |
SKF_VerifPIN | 校验 PIN |
SKF_UnblockPIN | 解锁PIN |
SKF_ClearSecueState | 清除应用安全状态 |
应用管理类系列函数:
函数名称 | 功 能 |
---|---|
SKF_CreateAppiatin | 创建应用 |
SKF_ErumApliation | 枚举应用 |
SKF_DeleteAppiation | 删除应用 |
SKF_OpenAplication | 打开应用 |
SKF_CloseApicaion | 关闭应用 |
文件管理类系列函数:
函 数 名 称 | 功 能 |
---|---|
SKF_CrateFile | 创建文件 |
SKF_DeleteFile | 删除文件 |
SKF_EnumFiles | 枚举文件 |
SKF_GetFielnfo | 获取文件信息 |
SKF_ReadFile | 读文件 |
SKF_WriteFile | 写文件 |
容器管理系列函数:
函数名称 | 功 能 |
---|---|
SKF_CreateContainer | 创建容器 |
SKF_DeleteContainer | 删除容器 |
SKF_EnumContainer | 枚举容器 |
SKF_OpenContainer | 打开容器 |
SKF_CloscContainer | 关闭容器 |
SKF.CetContainerType | 获得容器类型 |
SKF ImportCertifiate | 导入数字证书 |
SKF_ExportCertificate | 导出数字证书 |
密码服务类:
GMT 0018-2012
设备管理类函数:
- 打开设备∶SDF_OpenDevice
- 关闭设备∶SDF_CloseDevice
- 创建会话∶SDF_OpenSession
- 关闭会话∶SDF_CloseSession
- 获取设备信息;SDF_GetDevicelnfo
- 产生随机数∶SDF_GenerateRandom
- 获取私钥使用权限∶SDF_GetPrivateKeyAccessRight
- 释放私钥使用权限∶SDF_ReleasePrivateKeyAccessRight
密钥管理类函数:
- 导出 RSA 签名公钥∶SDF_ExportSignPublicKey_RSA
- 导出 RSA加密公钥∶SDF_ExportEncPublicKey_RSA
- 产生 RSA非对称密钥对并输出∶SDF_GenerateKeyPair_RSA
- 生成会话密钥并用内部 RSA 公钥加密输出∶SDF_GenerateKeyWithIPK_RSA
- 生成会话密钥并用外部 RSA公钥加密输出∶SDF_GenerateKeyWithEPK_RSA
- 导入会话密钥并用内部 RSA 私钥解密∶SDF_ImportKeyWithISK_RSA
- 基于 RSA算法的数字信封转换∶SDF_ExchangeDigitEnvelopeBaseOnRSA
- 导出 ECC签名公钥∶SDF_ExportSignPublicKey_ECC
- 导出 ECC加密公钥∶SDF_ExportEncPublicKey_ECC
- 产生 ECC非对称密钥对并输出∶SDF_GenerateKeyPair_ECC
- 生成会话密钥并用内部 ECC公钥加密输出∶SDF_GenerateKeyWithIPK_ECC
- 生成会话密钥并用外部 ECC公钥加密输出∶SDF_GenerateKeyWithEPK_ECC
- 导入会话密钥并用内部 ECC私钥解密∶SDF_ImportKeyWithISKECC
- 生成密钥协商参数并输出∶SDF_GenerateAgreementDataWithECC
- 计算会话密钥∶SDF_GenerateKeyWithECC
- 产生协商数据并计算会话密钥∶SDF_GenerateAgreementDataAndKeyWithECC
- 基于 ECC算法的数字信封转换∶SDF_ExchangeDigitEnvelopeBaseOnECC
- 生成会话密钥并用密钥加密密钥加密输出∶SDF_GenerateKeyWithKEK
- 导入会话密钥并用密钥加密密钥解密;SDF_ImportKeyWithKEK
- 销毁会话密钥∶SDF_DestroyKey
非对称算法运算类函数:
- 外部公钥 RSA 运算∶SDF_ExternalPublicKeyOperation_RSA
- 内部公钥 RSA 运算∶SDF_InternalPublicKeyOperation_RSA
- 内部私钥 RSA 运算∶SDF_InternalPrivateKeyOperation_RSA
- 外部密钥 ECC 验证∶SDF_ExternalVerify_ECC
- 内部密钥 ECC签名∶SDF_InternalSign_ECC
- 内部密钥 ECC验证∶SDF_InternalVerify_ECC
- 外部密钥 ECC加密∶SDF_ExternalEncrypt_ECC
杂凑运算类函数:
- 杂凑运算初始化∶SDF_HashInit
- 多包杂凑运算∶SDF_HashUpdate
- 杂凑运算结束∶SDF_HashFinal
用户文件操作类函数:
- 创建文件∶SDF_CreateFile
- 读取文件∶SDF_ReadFile
- 写文件∶SDF_WriteFile
- 删除文件∶SDF_DeleteFile
总结&分类
这些API包含的函数一般包含几个方面:设备管理、访问控制、密钥(密钥)管理、文件操作管理。
CryptoAPI体系主要有:基本加密函数、证书编/解码函数、证书库管理函数、简单消息函数、底层消息函数。
GMT 0016-2012和GMT 0018-2012差别不大,均含有RSA签名验签,ECC签名验签计算公钥等功能。0018有专门的杂凑运算函数以及可以直接对用户文件做操作。而0016则有专门函数产生导出数字证书。
三、调用代码
代码链接:https://gitee.com/amyonelse/research-on-exp1-api.git
产生随机数
运行截图:
进行签名
运行截图:
获取信息
运行截图: