一、任务详情

密码引擎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

CryptoAPI 系统体系结构

Web Crypto API

Web Cryptography API

CSP开发基础--CryptoAPI函数简介

三、实验内容

查找各种标准的原始文档,研究学习(至少包含Crypto API,PKCS#11,GMT 0016-2012,GMT 0018-2012)

Ⅰ.Crypto API#

1.基本加密函数#

①服务提供者函数

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

image-20210424152027712

②密钥的产生和交换函数

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

image-20210424152200411

image-20210424152319068

③编码/解码函数

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

image-20210424152437871

④数据加密/解密函数

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

image-20210424152524330

⑤哈希和数字签名函数

完成计算哈希、创建和校验数字签名

image-20210424152650914

image-20210424152721102

Ⅱ.PKCS#11#

简介#

一套称为公共密钥加密标准(Public-Key Cryptography Standards )的规范,既PKCS

适用范围#

本标准为那些保存密码信息,执行密码函数的设备确定一种程序设计接口(API),该接口称做Cryptoki。Cryptoki发“Crypto-Key”音,是cryptographic token interface (密码令牌接口)的缩写,它遵循一种基于对象的简单方法,提出技术独立性(各种各样的设备)和资源共享(多个应用程序访问多个设备)的目标,把设备的一种通用的逻辑视图,即密码令牌,提供给应用程序。

通用模型#

Cryptoki的通用模型如下图所示。模型从一个或多个必须执行某些密码操作的应用程序开始,以一个或多个密码设备结束(在密码设备上执行某些或全部操作)。一个用户可涉及也可不涉及一个程序。

image-20210424173115815

Cryptoki 为一个或多个密码设备提供一个接口,这些设备通过大量的槽在系统中运行。每个对应于一个物理阅读器或另一个设备接口的槽可包含一个令牌。当一台密码设备存在于阅读器中,一个令牌就存在于该槽中。当然,由于Cryptoki提供槽和令牌的逻辑视图,所以可能有其它的物理译码。多个槽可能共享一个阅读器。问题在于一个系统有相当多的槽,应用程序能连接到这些槽的其中任何一个或全部槽的令牌上。

密码设备可以按照某一命令集执行某些密码操作,这些命令通常要经过标准设备驱动程序,例如PCMCIA卡服务程序或槽服务程序。Cryptoki 使每个密码设备看起来逻辑上很象其它设备,而不管什么技术实现的。因此,应用程序不必直接与设备驱动器接口(或甚至不必知道包括那些设备);Cryptoki 隐藏了这些细节。的确,基础设备完全能用软件来实现,(例如,在一个服务器上运行的处理程序),不须专用硬件。

Cryptoki 或许可以作为支持接口功能的库来实现,而应用程序则与该库连接。应用程序可以直接与Cryptoki 连接,或者,Cryptoki 是一个所谓的“共享”库(或动态连接库),在这种情况下,应用程序动态地连接库。用Microsoft Windows和OS/2操作系统可以比较容易地生成数据库,并且在UNIX和DOS中也可相对容易地生成“共享”库。

由于新库可以使用,所以动态方法有许多优点;但从安全的角度来说,也有一些缺点。要特别指出的是,如果库能较容易地被替换,攻击者有可能用恶意制造的假库取而代之,以截取用户的PIN。即使编码签名技术能防止许多动态连接的安全危险,从安全角度来说,一般采用直接连接。总之,应用程序和Cryptoki 库之间的程序设计接口是相同的。

设备的种类和所支持的能力的种类将取决于专用Cryptoki 库。本标准只定义库的接口,不定义库的特征。要特别指出的是,并不是所有的库支持这个接口(因为不是所有的令牌支持所有的机制)中定义的机制(算法)。并且库也许只支持可使用的所有密码设备的一个子集。(当然,可以预料更多更好的设备种类将被开发,以支持多种令牌,而不是单个供应商提供的令牌。)只要开发出应用程序,就会形成Cryptoki 的接口、标准数据库和令牌“轮廓”。

Ⅲ.GMT 0016-2012#

结构模型#

智能密码钥匙应用接口位于智能密码钥匙应用程序与设备之间

image-20210424201254384

一个设备中存在设备认证密钥和多个应用,应用之间相互独立。

image-20210424201637053

应用由管理员PIN、用户PIN、文件和容器组成,可以存在多个文件和多个容器。

每个应用维护各自的与管理员PIN和用户PIN相关的权限状态。

一个应用的逻辑结构如图所示

image-20210424201920046

密码服务#

image-20210424212946635

image-20210424212955622

错误代码#

image-20210424213118189

image-20210424213127921

Ⅳ.GMT 0018-2012#

image-20210424213426456

image-20210424213438228

image-20210424213452940

image-20210424213504892

image-20210424213515056

image-20210424213531523

image-20210424213620484

image-20210424213632431

image-20210424213643387

image-20210424213730680

image-20210424213740443

image-20210424213751303

image-20210424213801880

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

  1. Crypto API:

    • Crypto API是一组用于加密和解密数据的功能集合。它通常用于处理敏感信息,如用户凭据、支付信息等。
    • 在编程中,你可以使用Crypto API来执行诸如对称加密(如AES)、非对称加密(如RSA)、散列函数(如SHA-256)等操作。
    • 你需要了解如何正确地调用这些功能,并了解不同算法之间的差异,以便选择适合你需求的加密方式。
  2. PKCS#11:

    • PKCS#11是一种标准的密码学令牌接口规范,用于定义与加密设备进行通信的API。
    • 在编程中,你可以使用PKCS#11来访问智能卡、USB加密令牌等加密设备,并执行数字签名、加密、解密等操作。
    • 需要注意的是,PKCS#11是一个跨平台的标准,因此你的代码可以在不同的操作系统上运行,只要相应的PKCS#11实现可用。
  3. GMT 0016-2012和GMT 0018-2012:

    • GMT 0016-2012和GMT 0018-2012是中国国家标准化管理委员会发布的关于密码技术的两个标准。
    • 这些标准提供了密码算法、密钥管理、安全协议等方面的规范和指南,旨在确保信息安全。
    • 在编程中,你需要了解这些标准,并按照其规范来实现相关功能,以确保你的应用程序满足相应的安全要求

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

 

(一)SKF接口

龙脉密码钥匙驱动实例工具等\mToken-GM3000\skf\samples\windows\EncryptData\EncryptData.sln

 

(二)Crypto API

1.龙脉密码钥匙驱动实例工具等\mToken-GM3000\csp\samples\CryptAPI\VC\EncryptDecryptFile\EncryptFile.sln

要在当前目录下先创建 20211422.txt

 

(三)PKCS#11

1.龙脉密码钥匙驱动实例工具等\mToken-GM3000\pkcs11\windows\samples\PKCStest\PKCStest.sln

(1)DES

 

 

(2)DES3

(3)RC2

 

(4)RC4

(5)RSA

 

(6)AES

 

 

2.龙脉密码钥匙驱动实例工具等\mToken-GM3000\pkcs11\windows\samples\GetUSBInfos\getusbinfos.sln

 相关代码:

Ⅰ.Crypto API#

Copy
解释
 
 
HCRYPTPROV hCryptProv;
HCRYPTHASH hCryptHash;
HCRYPTKEY hCryptKey;


CPAcquireContext(
    hCryptProv, NULL,
    MS_DEF_PROV,
    PROV_RSA_FULL,
    CRYPT_VERIFYCONTEXT
)//为应用程序创建一个上下文
    
CPCreateHash(
    hCryptProv,
    CALG_MD5,
    0,
    0,
    &hCryptHash
) //为应用程序创建一个上下文
    
static char szHash[]=”PISAHASHDATA”; //原始字符串
DWORD dwLen=strlen(szHash);
CPHashData(hCryptHash, (BYTE*)szHash, dwLen, 0);//散列输入的数据
CPDeriveKey(hCryptProv, CALG_RC2, hCryptHash, 0, &hCryptKey);//从一个数据散列中生成一个会话密钥,它保证生成的密钥互不相同

static char szEntry[]= “PISA2002”;
DWORD dwLenIn = strlen(szEntry);
DWORD dwLenOut=dwLenIn;
CPEncrypt(hCryptKey, 0, TRUE, 0, (BYTE*)szEntry, &dwLenOut, dwLenIn);//用来加密明文
CPDecrypt(hCryptKey, 0, TRUE, 0,(BYTE*)szEntry,&dwLenOut);//用来解密先前被加密的数据
CPDestroyKey(hCryptKey);//释放一个密钥句柄,释放后,句柄将无效,密钥将无法再被访问
CPDestroyHash(hCryptHash);//删除一个散列对象句柄
CPReleaseContext(hCryptProv, NULL);//释放CPAcquireContext.创建的上下文

Ⅱ.PKCS#11

CK_SESSION_HANDLE hSession;
CK_MECHANISM digestMechanism;
CK_ULONG ulStateLen;
CK_BYTE data1[] = {0x01, 0x03, 0x05, 0x07};
CK_BYTE data2[] = {0x02, 0x04, 0x08};
CK_BYTE data3[] = {0x10, 0x0F, 0x0E, 0x0D, 0x0C};
CK_BYTE pDigest[20];
CK_ULONG ulDigestLen;
CK_RV rv;

/* Initialize hash operation */
rv = C_DigestInit(hSession, &digestMechanism);//初始化消息杂凑计算操作,指定计算消息杂凑的算法
assert(rv == CKR_OK);

/* Start hashing */
rv = C_DigestUpdate(hSession, data1, sizeof(data1));//对多个分组的消息进行杂凑计算
assert(rv == CKR_OK);//返回成功或者失败

/* Find out how big the state might be */
rv = C_GetOperationState(hSession, NULL_PTR, &ulStateLen);//获取设备是否存在的状态
assert(rv == CKR_OK);//返回成功或者失败

/* Allocate some memory and then get the state */
pState = (CK_BYTE_PTR) malloc(ulStateLen);
rv = C_GetOperationState(hSession, pState, &ulStateLen);//获取设备是否存在的状态

/* Continue hashing */
rv = C_DigestUpdate(hSession, data2, sizeof(data2));//对多个分组的消息进行杂凑计算
assert(rv == CKR_OK);//返回成功或者失败

/* Restore state.  No key handles needed */
rv = C_SetOperationState(hSession, pState, ulStateLen, 0, 0);
assert(rv == CKR_OK);//返回成功或者失败

/* Continue hashing from where we saved state */
rv = C_DigestUpdate(hSession, data3, sizeof(data3));//对多个分组的消息进行杂凑计算
assert(rv == CKR_OK);//返回成功或者失败

/* Conclude hashing operation */
ulDigestLen = sizeof(pDigest);
rv = C_DigestFinal(hSession, pDigest, &ulDigestLen);
if (rv == CKR_OK) {
  /* pDigest[] now contains the hash of 0x01030507100F0E0D0C */
}//返回成功或者失败

Ⅲ.SKF接口#

Copy
解释
 
 
CK_FLAGS flags = 0;
CK_Dev_ID DevID;
CK_Dev_INFO DevInfo;


/* Block and wait for a slot event */
rv = SKF_WaitForSlotEvent(flags, &slotID, NULL_PTR);//等待设备的插拔事件
assert(rv == CKR_OK);//返回成功或者失败

/* See what’s up with that slot */
rv = SKF_GetDevInfo(slotID, &slotInfo);//获取设备的一些特征信息
assert(rv == CKR_OK);//返回成功或者失败
 

 

posted on 2024-04-08 11:09  20211422王俊凯  阅读(17)  评论(0编辑  收藏  举报