实验一-密码引擎-加密API研究

CryptoAPI函数

 

参考链接(https://blog.csdn.net/liuhuiyi/article/details/7778123?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-7.control&dist_request_id=1332041.22396.16193156746724489&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-7.control)

 

1.基本加密函数

CSP是真正实行加密的独立模块,他既可以由软件实现也可以由硬件实现。但是他必须符合CryptoAPI接口的规范。

每个CSP都有一个名字和一个类型。每个CSP的名字是唯一的,这样便于CryptoAPI找到对应的CSP。目前已经有9种CSP类型,并且还在增长。下表列出出它们支持的密钥交换算法、签名算法、对称加密算法和Hash算法。

 

 

 

服务提供者函数:

应用程序使用服务提供者函数来连接和断开一个CSP。下面就是主要的API:

 

 

 

 

 

 

 

 

密钥的产生和交换函数:

密钥产生函数创建、配置和销毁加密密钥。他们也用于和其他用户进行交换密钥。下面就是主要的一些函数:

 

 

 

 

编码/解码函数:

有一些编码/解码函数,他们可以用来对证书、证书撤销列表、证书请求和证书扩展进行编码和解码。以下就是这几个函数:

 

 

 

 

数据加密/解密函数: 

这些函数支持数据的加密/解密操作。CryptEncrypt 和CryptDecrypt 要求在被调用前指定一个密钥。这个密钥可以由CryptGenKey、CryptDeriveKey 或CryptImportKey 产生。创建密钥时要指定加密算法。CryptSetKeyParam 函数可以指定额外的加密参数。

 

 

 

 

哈希和数字签名函数:

这些函数在应用程序中完成计算哈希、创建和校验数字签名。

 

 

 

 

2、证书和证书库函数

这组函数管理、使用和取得证书、证书撤销列表和证书信任列表。这些函数可以分成一下几组:

 

证书库函数:

一个用户站点可以收集许多证书。这些证书是为这个站点的用户所使用的,证书描述了这个用户的具体身份。对于每个人,可能有一个以上的证书。证书库和其相关的函数提供了对库获得、枚举、验证和使用证书库里的信息。

以下就是这些函数:

 

 

 

 

 

 

 

 

 

 

 

 

维护函数:

CryptoAPI 提供了证书和证书库函数如下: 

 

 

 

 

 

 证书函数:

下列函数是针对于证书的。大多数函数都是处理CRL 和CTL 的。

 

 

 

 

 

 

 

 

 

证书撤销列表函数:

 

 

 

 

证书信任列表函数:

 

 

 

 

 

 

扩展属性函数:

 

 

 

 

 

 

3、证书验证函数

证书验证是通过CTL 和证书列表进行的。

使用CTL 的函数:

 

 

 

证书链验证函数:

 

 

 

 

 

 

 

 4、消息函数

CryptoAPI 消息函数包括两组:低级消息函数和简化消息函数。

低级消息函数直接和PKCS#7 消息工作。这些函数对传输的PKCS#7 数据进行编码,对接收到的PKCS#7 数据进行解码,并且对接收到的消息进行解密和验证。

简化消息函数是比较高级的函数,是对几个低级消息函数和证书函数的封装,用来执行指定任务。这些函数在完成一个任务时,减少了函数调用的数量,因此简化了CryptoAPI的使用。

低级消息函数:

 

 

 

简化消息函数:

 

 

 

 

 

 

 

 

 

 5、辅助函数

数据管理函数 

 

 

 

 

 

 

 

 

 数据转换函数

 

 

 

 

 

 增强密钥用法函数

 

 

 

 密钥标示函数

 

 

 

 

 

证书库回调函数

 

 

 

 

 

 

 

OID支持函数

 

 

 

 

 

 

 

 

 

远程对象恢复函数

 

 

 

PFX 函数

 

 

 

 

PKCS#11及CSP接口标准

RSA非对称密码算法的三个创始人的姓的第一个字母联合起来就是RSA了,他们三个创建的公司的名字也就叫做RSA。在RSA有一个著名的公钥算法的实验室,这个实验室颁发的一系列行业标准就称作为PKCS标准,其中PKCS#11(简称P11)就是针对密码设备的接口指令标准。目前最新的版本应该是2.3了。

P11模型中重要的概念之一是slot,也称为槽。一个slot为一个密码设备对象。某个打开的slot会话称之为session。Session之间存在不同的验证权限。而同一个slot的不同的session之间存在操作的互相影响性,同时在某些状况下,权限会发生同步。另外一个重要的概念是对象。P11中支持几种重要的对象,如公钥、私钥、对称密钥,数据对象等。

PKCS#11创建和支持下列对象:

 

 

 

PKCS#11的对象可根据其生命期长短的不同分成两大类:一类是持久存储的类对象,这类对象被保存在USB Key的安全存储区域当中,直到应用程序主动删除这些对象;另一类是会话对象,这类对象只存在于运行时建立的特定会话(Session对象)当中,一旦会话结束,这类对象也跟着被删除。决定对象生命期的模板属性是CKA_TOKEN,这是个布尔值,所有的对象都有这一属性。当该值为TRUE时,该对象将被保存到Key内的存储空间,否则,该对象保存在会话空间中,当会话结束后,该对象即销毁。

PKCS#11的对象除了生命期长短有分别之外,在访问权限上也有限制。所有的对象都可根据访问权限的不同分成两大类:一类是公开对象,这类对象是任何用户都可以访问的;另一类是私有对象,这一类对象只有身份被验证的用户才有权访问。决定对象的访问限制类型的模板属性是CKA_PRIVATE。这是个布尔值,所有的对象都有这一属性。应用程序可根据需要决定对象应为私有对象还是公开对象。

P11标准颁发了70余条指令。其中部分指令简介如下表:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 3、CSP接口标准

CSP接口标准为微软所颁发,在windows操作系统上通行。CSP中重要的概念是容器(container)。一个容器中具有一对公私钥。而证书却是这一对密钥的附加属性了。

CSP总共有23个函数接口。简介如下:

 

 

 

 

 

 

 

 

 

 

GMT 0016-2012

下列缩略语适用于本部分:
ECC:椭圆曲线算法(Elliptic Curve Cryptography)
IPK:内部加密公钥(Internal Public Key)
ISK:内部加密私钥(Internal Private Key)
EPK:外部加密公钥(External Public Key)
KEK:密钥加密密钥(Key Encrypt Key)

GM/T 0006设备定义信息如下:

 

 


实际数字结构定义:
typedef struct DeviceInfo_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;

GB/T 0018-2012
**# define RSAref_MAX_BIT S2048
**# define RSAref_MAX_LEN
((RSAref_MAX_BITS+7)/8)
**# define RSAref_MAX_PBITS
((RSAref_MAX_BITS+1)/2)
**#define RSAref_MAX_PLEN
((RSAref_MAX_PBITS+7)/8)
typedef struct RSArefPublicKey_st
unsigned int bits;
unsigned char m[RSAref_MAX_LEN];
unsigned char e[RSAref_MAX_LEN];
}RSArefPublicKey;
typedef struct RSArefPrivateKey_st
{
unsigned int bits;
unsigned char m[RSAref_MAX_LEN];
unsigned char e[RSAref_MAX_LEN];
unsigned char d[RSAref_MAX_LEN];
unsigned char prime[2][RSAref_MAX_PLEN]; unsigned char pexp[2][RSAref_MAX_PLEN]; unsigned char coef RSArefMAX_PLEN];
}RSArefPrivateKey;

ECC加密如下:

//******************************************
//设备管理
//******************************************
/*
功能:打开密码设备,返回设备句柄。
参数:
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_OpenDevice(void
* phDeviceHandle);
/*
功能:关闭密码设备,并释放相关资源。
参数:hDeviceHandle[in] 已打开的设备句柄
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_CloseDevice(void
 hDeviceHandle);
/*
功能: 创建与密码设备的会话。
已打开的设备句柄
hDeviceHandlein]参数:h
phessionHiandle[out]
返回与密码设备建立的新会话句柄成功
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_OpenSession(void
 hDeviceHandle, void** phSessionHandle);

/*
功能:关闭与密码设备已建立的会话,并释放相关资源。
参数:hSessionHandle[in] 与密码设备已建立的会话句柄
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_CloseSesson(void
 hSessionHandle);

/*
功能:获取密码设备能力描述。
参数:hSessionHandle[in] 与设备建立的会话句柄
pstDevicelnfo[our] 设备能力描述信息,内容及格式见设备信息定义成功
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_GetDeviceInfo(
void
 hSessionHandle,
DEVICEINFO* pstDeviceInfo);

/*
功能:获取指定长度的随机数。
参数:
hSessonHandle[in] 与设备建立的会话句柄
uiLegth[in] 欲获取的随机数长度
pucRandom[out] 缓冲区指针,用于存放获取的随机数
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_GenerateRandom(
void
 hSessionHandle,
unsigned int uiLength,
unsigned char* pucRandom);

/*
功能:获取密码设备内部存储的指定索引私钥的使用权。
参数:
hSessionHandle[in] 与设备建立的会话句柄
uiKeyIndex[in] 密码设备存储私钥的索引值
pucPassword[in] 使用私钥权限的标识码
uiPwdLength[in] 私钥访问控制码长度,不少于8 字节
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_GetPrivateKeyAccessRight(
void
 hSessionHandle,
unsigned int uiKeyIndex,
unsigned char* pucPassword,
unsigned int uiPwdLength);

/*
功能:释放密码设备存储的指定索引私钥的使用授权。
参数:
hSessonHandle[in] 与设备建立的会话句柄
uiKeyIndex[in] 密码设备存储私钥索引值成功
返回值∶0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_ReleasePrivateKeyAccessRight(
void
 hSessionHandle,
unsigned int uiKeyIndex);

      

 

 

GMT 0018-2012

 

实际数据结构定义∶

typedef struct Devicenfo_st{  

unsigned char IsuerName[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;

 

 

 

 

 

 

 

 

 

 

 

 

 

以龙脉GM3000Key为例,写出调用不同接口的代码(Crypto API,PKCS#11,SKF接口)

 

 

 

 

 

 

 

 

 

   加密文件

a)打开源文件

b)取得密钥容器(CSP)句柄

c)根据用户输入的密码创建一个会话密钥(即对称密钥,用于对原文件加密)

d)加密数据文件

e)清理工作,如释放Buffer空间、密钥句柄、CSP句柄等。

 

解密文件

a)打开加密文件(同上)

b)取得密钥容器(CSP)句柄(同上)

c)根据用户输入的密码创建一个会话密钥(即对称密钥,用于对原文件解密)(同上)

d)解密数据文件

e)清理工作,如释放Buffer空间、密钥句柄、CSP句柄等。(同上)

 

签名文件

a)打开源文件(同上)

b)取得密钥容器(CSP)句柄(同上)

c)取得签名用的密钥句柄(非对称RSA密钥)

g)清理工作,如释放Buffer空间、密钥句柄、CSP句柄等。(同上)

 

验证签名

a)打开文件(同上)

b)取得密钥容器(CSP)句柄(同上)

c)导入 pbKeyBlob 公钥

d)计算数据文件的Hash值,保存在Hash对象hHash中。(同上)

e)验证数字签名

f)清理工作,如释放Buffer空间、密钥句柄、CSP句柄等。(同上)

 

 

 

 

 

 

 

 

 

 

 

posted @ 2021-04-25 13:34  西瓦沙拉  阅读(236)  评论(0编辑  收藏  举报