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

任务详情
密码引擎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分)

一、查找各种标准的原始文档,研究学习

微软的Crypto API

crypto API提供了对称加密和非对称加密,并且提供了各种加密、解密的算法,要使用相应的算法进行加密解密,只需要对生成密钥的函数的相关参数改变一下即可。
加密与解密流程图:

CryptoAPI是一组函数,为了完成数学计算,必须具有密码服务提供者模块(CSP)。Microsoft通过捆绑RSA Base Provider在操作系统级提供一个CSP,使用RSA公司的公钥加密算法,更多的CSP可以根据需要增加到应用中。事实上,CSP有可能与特殊硬件设备(如智能卡)一起来进行数据加密。CryptoAPI接口允许简单的函数调用来加密数据,交换公钥,散列一个消息来建立摘要以及生成数字签名。它还提供高级的管理操作,如从一组可能的CSP中使用一个CSP。此外,CryptoAPI还为许多高级安全性服务提供了基础,包括用于电子商务的SET,用于加密客户机/服务器消息的PCT,用于在各个平台之间来回传递机密数据和密钥的PFX,代码签名等等。

PKCS#11

在密码系统中,PKCS#11是公钥加密标准(PKCS, Public-Key Cryptography Standards)中的一份子 ,由RSA实验室(RSA Laboratories)发布[1],它为加密令牌定义了一组平台无关的API ,如硬件安全模块和智能卡。
由于没有一个真正的标准加密令牌,这个API已经发展成为一个通用的加密令牌的抽象层。 PKCS#11 API定义最常用的加密对象类型( RSA密钥,X.509证书,DES /三重DES密钥等)和所有需要使用的功能,创建/生成,修改和删除这些对象。注意:pkcs#11只提供了接口的定义, 不包括接口的实现,一般接口的实现是由设备提供商提供的,如usbkey的生产厂商会提供 符合PKCS#11接口标准的API的实现。这样你只要通过接口调用API函数即可实现其功能。
架构

GMT 0016-2012

下列文件对于本文件的应用是必不可少的凡是注日期的引用文件,仅注日期的版本适用于本文件。凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于本文件。
①GM/T 0006 密码应用标识规范
②GM/T0009 SM2密码算法使用规范

术语和定义
下列术语和定义适用于本文件

应用 application
包括容器、设备认证密钥和文件的一种结构,具备独立的权限管理。

容器container
密码设备中用于保存密钥所划分的唯一性存储空间。

设备device
本标准中将智能密码钥匙统称为设备

设备认证 device authentication智能密码钥匙对应用程序的认证
设备认证密钥 device authentication key用于设备认证的密钥。
设备标签 label
设备的别名,可以由用户进行设定并存储于设备内部。

消息鉴别码 message authentication code; MAC消息鉴别算法的输出。
管理员PIN administrator PIN管理员的口令,为ASCII字符串
用户PIN user PIN
用户的口令,为ASCII字符串。

缩略语
下列缩略语适用于本规范: API 应用编程接口(Application Programming Interface)
PKI 公钥基础设施(Public Key Infrastructure)
PKCS#1
公钥密码使用标准系列规范中的第1部分,定义RSA公开密钥算法加密和签名机制(the Public-Key Cryptography Standard Part 1)
PKCS#5 公钥密码使用标准系列规范中的第5部分,描述一种利用从口令派生出来的安全密
钥加密字符串的方法(the Public-Key Cryptography Standard Part 5)
PIN 个人身份识别码(Personal Identification Number)
MAC 消息鉴别码(Message Authentication Code)

GMT 0018-2012

二、总结这些API在编程中的使用方式

Crypto API

密钥管理
在CryptoAPI中,支持两种类型的密钥:会话密钥、公/私密钥对。会话密钥也成为对称密钥,用于对称加密算法。为了保证密钥的安全性,在CryptoAPI中,这些密钥都保存在CSP内部,用户可以通过CryptExpoetKey以加密密钥快形式导出。公/私钥对用于非对称加密算法。非对称加密算法主要用于加解密会话密钥和数字签名。在CryptoAPI中,一般来说,大多数CSP产生的密钥容器包含两对密钥对,一对用于加密会话密钥,称为交换密钥对,一对用于产生数字签名,称为签名密钥对。在CryptoAPI中,所有的密钥都存储在CSP中,CSP负责密钥的创建,销毁,导入导出等操作。

数据编码/解码
CryptoAPI采用的编码方式为ASN.1,编码规则为DER,表示发送方发送数据时先把数据抽象为ASN.1对象,然后使用DER编码规则把ASN.1对象转化为可传输的0、1串;接受方接受到数据后,利用DER解码规则把0、1串转化为ASN.1对象,然后把ASN.1对象转化为具体应用支持的数据对象。

数据加/解密
在CryptoAPI中约定加密较大的数据块时,采用对称加密算法。通过其封装好的加解密函数来实现数据解加密操作。

哈希与数字签名
哈希与数字签名一般用于数据的完整性验证和身份鉴别。CryptoAPI中,通过其封装好的哈希与数字签名函数来实现相关操作。微软公司提供的CSP产生的数字签名遵循RSA标准(PKCS#6).

数字证书管理
数字证书主要用于安全通信中的身份鉴别。CryptoAPI中,对数字证书的使用管理函数分为证书与证书库函数、证书验证函数两大部分。

在VC++中开发CryptoAPI应用程序,需要预先设置一些编译环境。

1.需要包含以下头文件:

·#include <windows.h>

·#include <wincrypt.h>

2.包含的静态链接库:

链接CryptoAPI函数必须有静态库Crypto32.lib的支持,部分CryptoAPI函数可能还需要静态库advapi32.lib及CryptUI.lib的支持。

3.假如在VC++6.0上编译程序,则还需加上以下语句:

·#ifndef _WIN32_WINNT

·#define _WIN32_WINNT 0x0400

·#endif

三、列出这些API包含的函数,进行分类,并总结它们的异同

Crypto API

以下介绍几个编写Crypto API应用程序常用到得函数。

1.BOOLEAN CRYPTFUNC CryptAcquireContext(
HCRYPTPROV* phProv,   CSP句柄
LPCTSTR pszContainer,   密钥容器名称,指向密钥容器的字符串指针
LPCTSTR pszProvider,    指向CSP名称的字符串指针,如果为NULL,则使用默认的CSP
DWORD dwProvType, CSP类型
DWORD dwFlags 标志
);

这个函数是为了获得CSP句柄,函数通过phProv参数返回获得的CSP句柄。在CryptoAPI加密服务相关的所有操作都在CSP实现,CSP真正实行加密相关服务的独立模块,当应用程序需要加密相关服务时,比如:加解密操作、密钥产生于管理等,必须先获取某个CSP句柄。这时一般CryptoAPI编程的第一步。

2.BOOL CRYPTFUNC CryptGenKey(
HCRYPTPROV hProv,   //CSP句柄
ALG_ID Algid, //算法标志ID值。创建会话密钥时,它指定具体的加解密算法。指定算法时应注意具体的  

                         // CSP是否支持此算法。创建公/私密钥对时,参数应为AT_KEYEXCHANGE(交换密钥对)

                         //或AT_SIGNATURE(签名密钥对)。
DWORD dwFlags,    //说明创建密钥的长度及其它属性。
HCRYPTKEY* phKey   //新创建密钥句柄,函数通过这个参数返回创建密钥句柄。
);

在CryptoAPI中,构造密钥一般有两种方法,一通过哈希值,而通过随机数构造。上面这种就是通过随机数创建的。下面介绍利用哈希值创建的函数。

BOOL CRYPTFUNC CryptDeriveKey(
HCRYPTPROV hProv,
ALG_ID Algid,     //要产生密钥的对称加密算法
HCRYPTHASH hBaseData,    //哈希句柄,函数根据这个哈希句柄创建密钥。
DWORD dwFlags,    //指定密钥的类型。
HCRYPTKEY* phKey   //密钥句柄,函数通过这个参数返回创建的密钥句柄。
);

这个函数通过输入的哈希值hBaseData来创建一个密钥,通过密钥句柄phKey参数返回。注意:这个函数只能创建会话密钥,不能用于创建公/私密钥对。

3.BOOL CRYPTFUNC CryptCreateHash(
HCRYPTPROV hProv, //CSP句柄
ALG_ID Algid,   //哈希算法标识符
HCRYPTKEY hKey, // 如果哈希算法是密钥哈希,如HMACH或者MAC算法,就用此密钥句柄传递密钥。

                                   //对于非密钥算法,此参数为NULL。
DWORD dwFlags,   //保留,必须为0
HCRYPTHASH* phHash //哈希句柄,函数通过这个参数返回创建的哈希对象句柄。
);

这个函数初始化一个哈希句柄,它创建并返回一个CSP哈希句柄。

4.BOOL WINAPI CryptHashData(
HCRYPTHASH hHash,    //哈希句柄,创建的哈希值通过这个句柄返回
BYTE* pbData,    //指向要加入到哈希句柄的数据指针
DWORD dwDataLen,   // 数据长度
DWORD dwFlags   //标志
);

这个函数是计算一段数据的哈希值并加入到指定的哈希句柄中。在使用这个函数前必须通过CrpytHashData函数创建了一个哈希句柄。

5.BOOL WINAPI CryptEncodeObject(
__in          DWORD dwCertEncodingType,    //使用的编码类型。通常为 X509_ASN_ENCODING |

                                                                               //PKCS_7_ASN_ENCODING
__in          LPCSTR lpszStructType,            //要编码的结构体类型
__in          const void* pvStructInfo,   //欲编码的结构体指针,要和lpszStructType类型一致
__out         BYTE* pbEncoded,    //编码后结构体指针,当设置为NULL时用于获取其长度
__in_out      DWORD* pcbEncoded   //编码后的结构体长度
);

这个函数用于将pvStructInfo所指向的数据按照lpszStructType结构体类型编码。

6.BOOL WINAPI CryptDecodeObject(
__in          DWORD dwCertEncodingType,
__in          LPCSTR lpszStructType,
__in          const BYTE* pbEncoded,
__in          DWORD cbEncoded,
__in          DWORD dwFlags,
__out         void* pvStructInfo,
__in_out      DWORD* pcbStructInfo
);

这个函数是对上面编码后的数据进行解码,参数和上面编码函数的参数差不多,具体可以查看MSDN帮助文档。

PKCS#11

根据机制标记,可以分为几类:
CKF_ENCRYPT:加密类
CKF_DECRYPT:解密类
CKF_DIGEST:摘要类
CKF_SIGN:签名类
CKF_SIGN_RECOVER:可恢复签名类
CKF_VERIFY:验证类
CKF_VERIFY_RECOVER:可恢复验证类
CKF_GENERATE:密钥产生
CKF_GENERATE_KEY_PAIR:密钥对产生
CKF_WRAP:密钥封装
CKF_UNWRAP:密钥解封
CKF_DERIVE:密钥派生
1、通用接口

2、加密与解密

3、签名和消息鉴别

GMT 0016-2012

下列文件对于本文件的应用是必不可少的凡是注日期的引用文件,仅注日期的版本适用于本文件。凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于本文件。
①GM/T 0006 密码应用标识规范
②GM/T0009 SM2密码算法使用规范

术语和定义
下列术语和定义适用于本文件

应用 application
包括容器、设备认证密钥和文件的一种结构,具备独立的权限管理。

容器container
密码设备中用于保存密钥所划分的唯一性存储空间。

设备device
本标准中将智能密码钥匙统称为设备

设备认证 device authentication智能密码钥匙对应用程序的认证
设备认证密钥 device authentication key用于设备认证的密钥。
设备标签 label
设备的别名,可以由用户进行设定并存储于设备内部。

消息鉴别码 message authentication code; MAC消息鉴别算法的输出。
管理员PIN administrator PIN管理员的口令,为ASCII字符串
用户PIN user PIN
用户的口令,为ASCII字符串。

GMT 0018-2012

2、设备管理类函数

A. 打开设备:SDF_OpenDevice

B. 关闭设备:SDF_CloseDevice

C. 创建会话:SDF_OpenSession

D. 关闭会话:SDF_CloseSession

E. 获取设备信息:SDF_GetDeviceInfo

F. 产生随机数:SDF_GenerateRandom

G. 获取私钥使用权限:SDF_GetPrivateKeyAccessRight

H. 释放私钥使用权限:SDF_ReleasePrivateKeyAccessRight

3、密钥管理类函数

A. 导出RSA签名公钥:SDF_ExportSignPublicKey_RSA

B. 导出RSA加密公钥:SDF_ExportEncPublicKey_RSA

C. 产生RSA非对称密钥对并输出:SDF_GenerateKeyPair_RSA

D. 生成会话密钥并用内部RSA公钥加密输出:SDF_GenerateKeyWithIPK_RSA

E. 生成会话密钥并用外部RSA公钥加密输出:SDF_GenerateKeyWithEPK_RSA

F. 导入会话密钥并用内部RSA私钥解密:SDF_ImportKeyWithISK_RSA

G. 基于RSA算法的数字信封转换:SDF_ExchangeDigitEnvelopeBaseOnRSA

H. 导出ECC签名公钥:SDF_ExportSignPublicKey_ECC

I. 导出ECC加密公钥:SDF_ExportEncPublicKey_ECC

J. 产生ECC非对称密钥对并输出:SDF_GenerateKeyPair_ECC

K. 生成会话密钥并用内部ECC公钥加密输出:SDF_GenerateKeyWithIPK_ECC

L. 生成会话密钥并用外部ECC公钥加密输出:SDF_GenerateKeyWithEPK_ECC

M. 导入会话密钥并用内部ECC私钥解密:SDF_ImportKeyWithISK_ECC

N. 生成密钥协商参数并输出:SDF_GenerateAgreementDataWithECC

O. 计算会话密钥:SDF_GenerateKeyWithECC

P. 产生协商数据并计算会话密钥:SDF_GenerateAgreementDataAndKeyWithECC

Q. 基于ECC算法的数字信封转换:SDF_ExchangeDigitEnvelopeBaseOnECC

R. 生成会话密钥并用密钥加密密钥加密输出:SDF_GenerateKeyWithKEK

S. 导入会话密钥并用密钥加密密钥解密:SDF_ImportKeyWithKEK

T. 导入明文会话密钥:SDF_ImportKey

U. 销毁会话密钥:SDF_DestroyKey

4、非对称算法运算类函数

● 外部公钥RSA运算:SDF_ExternalPublicKeyOperation_RSA

● 外部私钥RSA运算:SDF_ExternalPrivateKeyOperation_RSA

● 内部公钥RSA运算:SDF_InternalPublicKeyOperation_RSA

● 内部私钥RSA运算:SDF_InternalPrivateKeyOperation_RSA

● 外部密钥ECC签名:SDF_ExternalSign_ECC

● 外部密钥ECC验证:SDF_ExternalVerify_ECC

● 内部密钥ECC签名:SDF_InternalSign_ECC

● 内部密钥ECC验证:SDF_InternalVerify_ECC

● 外部密钥ECC加密:SDF_ExternalEncrypt_ECC

● 外部密钥ECC解密:SDF_ExternalDecrypt_ECC

5、对称算法运算类函数

● 对称加密:SDF_Encrypt

● 对称解密:SDF_Decrypt

● 计算MAC:SDF_CalculateMAC

6、杂凑运算类函数

● 杂凑运算初始化:SDF_HashInit

● 多包杂凑运算:SDF_HashUpdate

● 杂凑运算结束:SDF_HashFinal

7、用户文件操作类函数 A) 创建文件:SDF_CreateFile B) 读取文件:SDF_ReadFile C) 写文件:SDF_WriteFile D) 删除文件:SDF_DeleteFile

四、以龙脉GM3000Key为例,写出调用不同接口的代码(Crypto API,PKCS#11,SKF接口),把运行截图加入博客,并提供代码链接

PKCS#11

pkcstest

getusbinfo


能够看到正确显示了key的信息

SKF

输入密码:

EncryptData

输入口令:

Crypto API

encryptfile

输入文件名:

输入password:

输入口令:

posted @ 2022-04-21 17:16  20191223张俊怡  阅读(259)  评论(0编辑  收藏  举报