实验一-密码引擎-加密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句柄等。(同上)