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

发布时间 2023-03-30 10:08:40作者: Zzangg

研究以上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

研究学习

基本加密函数

  • 用于连接到云解决方案提供商的上下文函数。 这些函数使应用程序能够按名称选择特定的云解决方案提供商,或选择可以提供所需功能类的特定云解决方案提供商。
  • 用于生成和存储加密密钥的密钥生成函数。 完全支持更改 链接模式、 初始化向量和其他加密功能。 有关详细信息,请参阅密钥生成和Exchange函数。
  • 用于交换或传输密钥的密钥交换函数。 有关详细信息,请参阅加密密钥存储和Exchange以及密钥生成和Exchange函数。

证书编码/解码函数

  • 用于加密或解密数据的函数。 还支持 哈希 数据。 有关详细信息,请参阅数据加密和解密函数和数据加密和解密。

证书Microsoft Store函数

  • 用于管理数字证书集合的函数。 有关详细信息,请参阅数字证书和证书Microsoft Store函数。

简化的消息函数

  • 用于加密和解密消息和数据的函数。
  • 用于对消息和数据进行签名的函数。
  • 用于验证已接收消息和相关数据的签名的真实性的函数。

低级别消息函数

  • 用于执行简化消息函数执行的所有任务的函数。 低级别消息函数比简化的消息函数更灵活,但需要更多的函数调用。 有关详细信息,请参阅 低级别消息低级别消息函数

image

每个功能区域在其函数名称中都有一个关键字,指示其功能区域。

功能区域 函数名称约定
基本加密函数 地穴
编码/解码函数 地穴
证书存储函数 存储
简化的消息函数 消息
低级别消息函数 Msg

使用方式

使用CryptoAPI编写一个文件保护程序,具有如下功能:
(1)给定明文文件,生成加密文件,同时产生文件的数字签名文件;
(2)给定密文文件,解密出明文文件,并验证签名的正确性。
在不安全的网络上进行安全的数据传输涉及三个方面的要求:信息隐藏,身份鉴别和完整性检验。CryptoAPI除了提供上述三个功能外还提供标准的ASN.1编码、解码,信息解密,数字证书和证书存储区的管理,证书信任列表、吊销列表和证书有效性检查等功能。

  1. 信息隐藏

信息隐藏的意义是保障信息内容只能被特定的人获取。信息隐藏通常是使用某种形式的密码学方式。数据加密算法能保障信息的安区隐藏和传输。数据加密算法是将明文数据经过一定的变换使其看上去是一组毫无意义的数据。在没有加密密钥的情况下,对于好的加密算法想从密文获取明文信息是不可能的。被加密的数据可以是任意的ASCII编码文本文件,数据库文件,和任意需要进行安全传输的数据。这里,“信息”是指任意的一段数据,“明文”是指任意一段没有被加密的数据,“密文”是指任意一段加密的数据。被加密的数据可以在不安全的通道上进行传输而不伤害其安全性。之后,密文可以被还原成明文。
  数据加密和解密的概念是:对数据加密的时候需要一个加密密钥,相当于门上的一把钥匙。解密的时候,需要使用一个解密密钥来解开数据。加密密钥、解密密钥可以相同也可以不相同。
  加密密钥必须小心保存,给其它用户的时候也必须通过安全的通道传递。对解密密钥的访问权限必须小心控制,因为拥有解密密钥意味着可以解开所有相应加密密钥加密的信息。

  1. 身份鉴别
      安全通讯的前提是通讯的双方知道对方的身份。身份鉴别的任务就是鉴别一个用户或者实体的真实身份。标识用户身份的文档通常被称为信任状或者凭证。
      身份鉴别有时候也用来判定接受的数据就是被发送的数据。如果A向B发送了一段数据,B需要鉴别这段数据就是A发出去的,而不是其它冒充A发出去的。为了满足这类验证的需求,CryptoAPI提供数字签名和校验函数,用来对信息进行鉴别。
      因为在计算机网网络上传输的数据与用户之间并没有物理连接,因此对数据进行鉴别的凭证也必须能够在网络上进行传输。这种凭证必须由受信任的凭证发行机构发行。
      数字证书就是平常说的证书就是这种凭证,是计算机在网络上进行身份验证的有效凭证。
      数字证书是由一个被称为证书机构的信任组织或实体颁发的凭证。它包含与证书对应的用户公钥以及其它一些记录证书主题和用户信息的数据。证书机构只有在验证了证书主题和证书对应的用户公钥的有效性之后才会签发证书。
      证书申请者和证书机构之间交换签发证书信息可以使用物理介质,比如软盘,进行传输。通常,这种信息都是在计算机网络上进行完成的。证书机构使用被信任的服务程序处理用户的请求和证书的签发工作。

  2. 完整性检验
      任何通过不安全介质传输的信息都可以被意外或蓄意的修改。在现实世界中,盖章、签名就是用来提供和证明信息完整性的工具。
      信息的接收者不但需要确定信息是由谁发送的,还要确定自己收到的信息是发送者发送的信息,而没有任何的变化。要建立数据的完整性检测机制,不仅要发送信息本身,还要发送用来校验数据的信息,这一信息通常被称作哈希值。数据和验证信息都可以与数字签名一起发送来证明其完整性。

常用函数

点击查看代码
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编程的第一步。
点击查看代码
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参数返回。注意:这个函数只能创建会话密钥,不能用于创建公/私密钥对。
点击查看代码
BOOL CRYPTFUNC CryptCreateHash(
HCRYPTPROV hProv, //CSP句柄
ALG_ID Algid,   //哈希算法标识符
HCRYPTKEY hKey, // 如果哈希算法是密钥哈希,如HMACH或者MAC算法,就用此密钥句柄传递密钥。

                                   //对于非密钥算法,此参数为NULL。
DWORD dwFlags,   //保留,必须为0
HCRYPTHASH* phHash //哈希句柄,函数通过这个参数返回创建的哈希对象句柄。
);
这个函数初始化一个哈希句柄,它创建并返回一个CSP哈希句柄。
点击查看代码
BOOL WINAPI CryptHashData(
HCRYPTHASH hHash,    //哈希句柄,创建的哈希值通过这个句柄返回
BYTE* pbData,    //指向要加入到哈希句柄的数据指针
DWORD dwDataLen,   // 数据长度
DWORD dwFlags   //标志
);
这个函数是计算一段数据的哈希值并加入到指定的哈希句柄中。在使用这个函数前必须通过CrpytHashData函数创建了一个哈希句柄。

API函数

服务提供者函数:

image

密钥的产生和交换函数:

image

数据加密/解密函数:

image

哈希和数字签名函数:

image

维护函数:

image

证书函数:

image

低级消息函数:

image

简化消息函数:

image

辅助函数

image

OID支持函数

image

(二)RAS公司的PKCS#11标准

研究学习

PKCS#11
PKCS11密码令牌接口标准中文版
OASIS PKCS 11 TC

PKCS#11是公钥加密标准Public-Key Cryptography Standards中的一份子,由RSA实验室发布。
  PKCS#11标准定义了与密码令牌的独立于平台的API,API本身命名为Cryptoki,这个API已经发展成为一个通用的加密令牌的抽象层。
  PKCS#11主要是应用于智能卡和HSM。
  PKCS#11为使用加密Token的应用程序提供统一的编程接口,独立于设备,屏蔽加密设备的复杂性,应用程序可以方便地更换设备。
  PKCS密码中间件位于上层应用和底层安全设备之间,应用基于 PKCS#11 标准接口开发各类应用程序。主要包括2个库

主API库:提供给应用的PKCS11接口。
tokenDLL库:由主 API 库调用,完成从上向下到指定设备的套接。
安全密码设备:安全服务资源和实施的载体,完成具体安全功能支撑。

PKCS #11模型中重要的概念之一是slot,也称为槽。一个slot为一个密码设备对象。某个打开的slot会话称之为session。Session之间存在不同的验证权限,而同一个slot的不同的session之间存在操作的互相影响性,同时在某些状况下,权限会发生同步。另外一个重要的概念是对象,PKCS #11中支持几种重要的对象,如公钥、私钥、对称密钥,数据对象等。
  PKCS#11创建和支持下列对象:
  PKCS#11的对象可根据其生命期长短的不同分成两大类:一类是持久存储的类对象,这类对象被保存在USB Key的安全存储区域当中,直到应用程序主动删除这些对象;另一类是会话对象,这类对象只存在于运行时建立的特定会话(Session对象)当中,一旦会话结束,这类对象也跟着被删除。
  PKCS#11的对象除了生命期长短有分别之外,在访问权限上也有限制。所有的对象都可根据访问权限的不同分成两大类:一类是公开对象,这类对象是任何用户都可以访问的;另一类是私有对象,这一类对象只有身份被验证的用户才有权访问。决定对象的访问限制类型的模板属性是CKA_PRIVATE。

使用方式

  1. 架构
    image

  2. 会话状态
    image

  3. 对象
    image

函数

PKCS#11的对象可根据其生命期长短的不同分成两大类:

  • 持久存储的类对象,这类对象被保存在USB Key的安全存储区域当中,直到应用程序主动删除这些对象;
  • 会话对象,这类对象只存在于运行时建立的特定会话(Session对象)当中,一旦会话结束,这类对象也跟着被删除。
    决定对象生命期的模板属性是CKA_TOKEN,这是个布尔值,所有的对象都有这一属性。当该值为TRUE时,该对象将被保存到Key内的存储空间,否则,该对象保存在会话空间中,当会话结束后,该对象即销毁。
    P11标准颁发了70余条指令。其中部分指令简介如下表:

image
image

image

image

image

(三)GMT 0016-2012 智能密码钥匙密码应用接口规范

研究学习

GM/T 0016-2012

接口规范

GMT 0016-2012是国家规定的智能密码钥匙密码应用接口规范,规定了基于PKI密码体制的智能密码钥匙密码应用接口,描述了密码应用接口的函数、数据类型、参数的定义和设备的安全要求。适用于智能密码钥匙产品的研制、使用和检测。
规范性引用文件

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

使用方式

image

image

函数

image

image
image
image

image

image

image

(四)GMT 0018-2012密码设备应用接口规范

GMT 0018-2012
接口标准

GMT 0018-2012标准规定了公钥密码基础设施应用技术体系下服务类密码设备的应用接口标准。适用于服务类密码设备的研制、使用,以及基于该类密码设备的应用开发,也可用于指导该类密码设备的检测。
规范性引用文件

下列文件对于本文件的应用是必不可少的。凡是注日期的引用文件,仅注日期的版本适用于本文件;凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于本文件;GM/T 0006密码应用标识规范;GM/T AAAA SM2密码算法使用规范。
  其中还包括了对部分术语的规定:
image

使用方式

image

API函数

设备管理类函数包括以下具体函数:

A.打开设备:SDF_OpenDevice
B.关闭设备:SDF_CloseDevice
C.创建会话:SDF_OpenSession
D.关闭会话:SDF_CloseSession
E.获取设备信息:SDF_GetDeviceInfo
F.产生随机数:SDF_GenerateRandom
G.获取私钥使用权限:SDF_GetPrivateKeyAccessRight
H.释放私钥使用权限:SDF_ReleasePrivateKeyAccessRight

密钥管理类函数

导出 RSA 签名公钥∶SDF_ExportSignPublicKey_RSA
导出 RSA 加密公钥∶SDF_ExportEncPublicKey_RSA
产生 RSA非对称密钥对并输出∶SDF_GenerateKeyPair_RSA
生成会话密钥并用内部 RSA公钥加密输出∶SDF_GenerateKeyWithIPK_RSA
生成会话密钥并用外部 RSA公钥加密输出∶SDF_GenerateKeyWithEPK_RSA
导入会话密钥并用内部 RSA私钥解密∶SDF_ImportKeyWithISK_RSA
基于 RSA 算法的数字信封转换∶SDF_ExchangeDigitEnvelopeBaseOnRSA
导出 ECC签名公钥∶SDF_ExportSignPublicKey_ECC
导出 ECC 加密公钥∶SDF_ExportEncPublicKey_ECC
产生 ECC非对称密钥对并输出∶SDF_GenerateKeyPair_ECC
生成会话密钥并用内部 ECC公钥加密输出∶SDF_GenerateKeyWithIPK_ECC
生成会话密钥并用外部 ECC公钥加密输出:SDF_GenerateKeyWithEPK ECC
导入会话密钥并用内部 ECC私钥解密∶SDF_ImportKeyWithISK_ECC
生成密钥协商参数并输出;SDF_GenerateAgreementDataWithECC
计算会话密钥∶SDF_GenerateKeyWiuhECC
产生协商数据并计算会话密钥∶SDF_GenerateAgreementDataAndKeyWithECC
基于 ECC算法的数字信封转换∶SDF_ExchangeDigitEnvelopeBaseOnECC
生成会话密钥并用密钥加密密钥加密输出∶SDF_GenerateKeyWithKEK
导入会话密钥并用密钥加密密钥解密∶SDF_ImportKeyWithKEK
销毁会话密钥∶SDF_DestroyKey

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

1. SKF接口

image

image

2. Crypto API

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

image

image
加密后的文件:

image

解密文件:
image

image

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

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

des:
image

des3:
image

rc2:
image

rc4:
image

rsa:
image

aes:
image

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

image

密钥生成和Exchange函数