任务要求
密码引擎API的主要标准和规范包括:
1 微软的Crypto API
2 RAS公司的PKCS#11标准
3 中国商用密码标准:GMT 0016-2012 智能密码钥匙密码应用接口规范,GMT 0018-2012密码设备应用接口规范等
研究以上API接口,总结他们的异同,并以龙脉GM3000Key为例,写出调用不同接口的代码,提交博客链接和代码链接。
内容:
0 查找各种标准的原始文档,研究学习(至少包含Crypto API,PKCS#11,GMT 0016-2012,GMT 0018-2012)(5分)
1 总结这些API在编程中的使用方式(5分)
2 列出这些API包含的函数,进行分类,并总结它们的异同(10分)
3 以龙脉GM3000Key为例,写出调用不同接口的代码(Crypto API,PKCS#11,SKF接口),把运行截图加入博客,并提供代码链接(10分)
研究学习原始文档
https://blog.csdn.net/lassewang/article/details/7900113
http://www.doc88.com/p-9117249687786.html
https://www.doc88.com/p-1146168706325.html
https://blog.csdn.net/weixin_46014245/article/details/116117513
总结使用方式
Crypto API
CryptoAPI体系主要由一下几部分组成:
基本加密函数、证书编码与解码函数、证书存储函数、简化信息处理函数、底层信息处理函数。前三者可用于对敏感信息进行加密或签名处理,可保证网络传输信心的私有性;后两者通过对证书的使用,可保证网络信息交流中的认证性。
PKCS#11
Cryptoki 的主要目标是一个低级程序接口,该接口将设备的细节抽象化,并把密码设备的通用模型—密码令牌,或简称令牌—提供给应用程序。
Cryptoki的通用模型如下图所示。模型从一个或多个必须执行某些密码操作的应用程序开始,以一个或多个密码设备结束(在密码设备上执行某些或全部操作)。一个用户可涉及也可不涉及一个程序。
SKF
针对支持国密算法USB KEY设备的应用,我国颁布一个行业标准《智能密码钥匙应用接口规范》(GM/T0016-2012),市面上销售的国密算法的USB KEY设备必须支持这个接口规范。因此,只要根据这个规范开发的应用程序,就可以兼容使用不同厂家及品牌的USB KEY产品。由于此规范中函数名称都以SKF开头,所以我们一般把按照此规范提供的设备开发接口库叫做SKF库或SKF接口。
智能密码钥匙密码应用接口位于智能密码钥匙应用程序与设备之间,如下图所示
应用由管理员PIN,用户PIN、文件和容器组成,可以存在多个文件和多个容器。每个应用维护各自的与管理员PIN和用户PIN相关的权限状态。
一个应用的逻辑结构如下图所示
列出这些API包含的函数,进行分类,并总结它们的异同
Crypto API
1、基本加密函数:服务提供者函数、密钥的产生 和交换函数、编码/解码函数、数据加密/解密函数、哈希和数字签名函数
2、证书和证书库函数:证书库函数、维护函数、证书函数、证书撤销列表函数、证书信任列表函数、扩展属性函数
3、证书验证函数:使用CTL的函数、证书链验证函数
4、消息函数:低级消息函数、简化消息函数
5、辅助函数:数据管理函数、数据转换函数、增强密钥用法函数、密钥标示函数、证书库回调函数、OID支持函数、远程对象恢复函数、PFX函数
PKCS#11
1、通用目的函数
2、槽和令牌管理函数
3、会话管理函数
4、对象管理函数
5、加密函数
6、解密函数
7、消息摘要函数
8、签名和MAC函数
9、验签和MAC函数
10、双重目的的加密
11、密钥管理函数
12、随机数生成函数
13、并行功能管理函数
14、呼叫返回函数
SKF
1、设备管理函数
2、访问控制函数
3、应用管理函数
4、文件管理函数
5、容器管理函数
6、密码服务函数
得到国密证书
根据国密标准,一种设备类型可以有多个设备(Device),每一个设备内可以有多个应用(Application),每一个应用里可以有多个容器(Container),每个容器里可以有一对证书(Certificate):签名证书和加密证书。
因此,应按照下列顺序依次调用相关接口:
1.SKF_EnumDev(BOOL bPresent, LPSTR szNameList, ULONG *pulSize);
调用这个方法用来遍历当前电脑上的设备,这个方法的第一个参数一般传TRUE,表示遍历的是插上的设备;第二个参数就是返回的设备名称列表;第三个参数是设备名称列表缓冲区长度。按照惯例,这个方法应该被调用两次:第一次szNameList传NULL,pulSize返回长度;第二次给szNameList分配pulSize长度,返回设备列表,每个设备的名称以单个’\0’结束,以双’\0’表示列表的结束。
2.SKF_ConnectDev(LPSTR szName, DEVHANDLE *phDev);
通过循环调用这个方法用来连接每一个具体的设备,szName为设备名,即上面方法得到的列表中的设备名;返回phDev为设备句柄。
3.SKF_EnumApplication(DEVHANDLE hDev, LPSTR szAppNameList,ULONG *pulSize);
得到设备句柄后,再通过此方法枚举得到设备里的应用列表。hDev为连接设备时返回的设备句柄;szAppNameList返回应用名称列表;pulSize是列表缓冲区长度。这个方法也是照例要调用两次,不再赘述。同样,每个应用的名称以单个’\0’结束,以双’\0’表示列表的结束。
4.SKF_OpenApplication(DEVHANDLE hDev, LPSTR szAppName, HAPPLICATION *phApplication);
通过循环调用此方法打开应用列表里的每一个应用,hDev为连接设备时返回的设备句柄;szAppName是要打开的应用名称;phApplication为返回的应用句柄。
5.SKF_EnumContainer(IN HAPPLICATIONhApplication, OUT LPSTRszContainerNameList, OUT ULONG*pulSize)
拿到应用句柄后,我们就可以用此方法遍历应用中的所有容器了。hApplication是应用句柄;szContainerNameList是返回的容器名称列表;pulSize是列表长度;后面的就不用了多说了。
6.SKF_OpenContainer(HAPPLICATION hApplication,LPSTR szContainerName,HCONTAINER *phContainer);
循环调用此方法打开每一个容器。hApplication是应用句柄;szContainerName是要打开的容器名称;phContainer是返回的容器句柄。
7.SKF_ExportCertificate(HCONTAINER hContainer, BOOL bSignFlag, BYTE* pbCert, ULONG *pulCertLen);
最后就可以通过这个方法取得每个容器里的证书。hContainer是容器句柄;bSignFlag为导出的证书类型; TRUE表示导出的是签名证书;FALSE表示导出加密证书。pbCert为返回的证书数据,pulCertLen是证书数据的长度。同样需两次调用。