实验一-密码引擎-加密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:
输入口令: