实验一-密码引擎-加密API研究
实验一-密码引擎-加密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研究

一、微软的CryptoAPI
- Windows CryptoAPI是Microsoft 公司提出的安全加密应用服务框架,也是PKI推荐使用的加密 API。它提供了在Win32 环境下使用认证、编码、加密和签名等安全服务时的标准加密接口,用于增强应用程序的安全性与可控性。应用开发者可以在不了解复杂的加密机制和加密算法的情况下,简便、快速地开发出标准、通用和易于扩展的安全加密应用程序。
- CryptoAPI 提供的功能主要有:密钥管理、数据加密和解密、数字签名和验证、证书管理、可信根证书管理、数据编码和解码、数字证书编码和解码、PKCS#7 标准格式编码和解码等。
- 利用CryptoAPI,开发者可以给基于Windows的应用程序添加安全服务,包括: ASN.1编码及解码、数据加密/解密、身份论证、数字证书管理,同时支持PKI、对称密码技术等。应用程序开发者直接使用这些安全功能而无须了解其底层实现。
1. 加密密钥
- 密钥是密码体系操作的中心,它们必须安全保存,任何人获得某个密钥则对此密钥有关的任何数据都拥有了访问的权限。例如,某人得到了加密某文件的密钥,则他就可以解密此文件了。再比如,获取了对某消息签名的密钥,则可以伪造数字签名。
- 在CryptoAPI中,支持两种类型密钥:会话密钥、公/私密钥对。
- 会话密钥也称为对称密钥,用于对称加密算法,例如RC2、RC4、DES等。在CryptoAPI中,一般使用CryptGenKey 或 CryptDeriveKey函数产生会话密钥。为了保证密钥的安全性,这些密钥都保存在CSP内部。当然,用户也可以通过CryptExportKey函数把密钥以加密密钥块形式导出到具体应用空间内,以备以后使用或传输给其他用户。
- 公/私密钥对(包括公钥、私钥)用于非对称加密算法,例如RSA等。非对称加密算法主要用于加解密会话密钥和数字签名。在CryptoAPI中,一般来说,大多数 CSP产生的密钥容器包含两对密钥对,一对用于加密会话密钥,称为交换密钥对,一对用于产生数字签名,称为签名密钥对;但也有些CSP没有存储密钥对,或者存储不止两对密钥对。
- 在CryptoAPI中,所有的密钥都存储在CSP,CSP负责产生、销毁密钥,并使用它们完成各种密码操作。也可以利用CryptoAPI函数从CSP中导出密钥。
2. 数据编码/解码
- 通过通信媒介(例如电话线路)传输数据,必须先把数据序列化,即把数据转化为0、1串。在序列化操作中,接到数据的计算机必须能够把数据转化为其原始格式。序列化完成的操作规则称为通信协议,它由软件和数据传输硬件共同完成,其协议一般包含多层,图3-3为一个简化了的通信协议层。
- 下图表示:计算机1应用程序层先传输原文数据到编码/解码层,编码/解码层编码原文数据为计算机字节流,然后发送到硬件层,硬件层把字节流数据转化为0、1串流传输到计算机2。计算机2接到数据后,反向操作,转化0、1串流为计算机字节流,发送到编码/解码层,编码/解码层解码计算机字节流为原文数据。
- 一种可接受的软件设计原理是使用抽象化,即根据问题或对象的一般参数来描述,而不是要描述解决问题的所有细节或对象的所有细节。利用抽象化,设计者说明软件对象的特定性质而不必关心其具体实现,它简化了说明文档。抽象化是大多数现代软件规范的特点,并且多数通信协议都包含一些列的抽象化。
- 简化通信协议层
- 描述抽象对象的一个普遍方式为:ASN.1(抽象语法标记1),ASN.1在CCITT推荐文件X.208中定义,描述对象转换为0、1串的ASN.1规则称为DER(精确编码规则),在CCITT推荐文档X.509 8.7节定义。CryptoAPI采用的就是这种编码方式,表示数据发送方发送时先把数据抽象为ASN.1对象,然后使用DER编码规则把ASN.1对象转化为可传输的0、1串;接收方接到数据后,利用DER解码规则把0、1串转化为ASN.1对象,然后再把ASN.1对象转化为具体应用支持的数据对象。
3. 数据加/解密
- 把明文转化为密文的过程称为加密,反之把密文转化为明文的过程称为解密。加密较大的数据,CryptoAPI中约定用对称加密算法,这种算法中,在加密和解密过程中都使用同一个对称密钥或会话密钥。CryptoAPI中,通过其封装好的加解密函数来实现数据加解密操作,不同CSP提供不同的加解密算法,但常用的算法,一般CSP都提供。
4. 哈希与数字签名
- 哈希与数字签名一般用于确定数据的完整性和身份鉴别。CryptoAPI中,通过其封装好的哈希与数字签名函数来实现相关操作。微软提供的CSP产生的数字签名遵循RSA标准(PKCS#6),其他CSP可能遵循其他标准。
5. 数字证书
- 数字证书主要用于安全通信中的身份鉴别。CryptoAPI中,对数字证书的使用管理分为证书与证书库函数、证书验证函数。
6.摘要算法
1) CryptAcquireContext
BOOL CryptAcquireContext (
HCRYPTPROV* phProv,
LPCTSTR pszContainer,
LPCTSTR pszProvider,
DWORD dwProvType,
DWORD dwFlags
)
2)CryptCreateHash
BOOL CryptCreateHash(
HCRYPTPROV hProv,
ALG_ID Algid,
HCRYPTKEY hKey,
DWORD dwFlags,
HCRYPTHASH *phHash
)
3) CryptHashData
BOOL CryptHashData(
HCRYPTHASH hHash,
BYTE* pbData,
DWORD dwDataLen,
DWORD dwFlags
)
4) CryptGetHashParam
BOOL CryptGetHashParam(
HCRYPTHASH hHash,
DWORD dwParam,
BYTE *pbData,
DWORD *pdwDataLen,
DWORD dwFlags
)
8.对称加密
对称加密中常用的方式是根据用户输入的口令加解密文档,即基于口令派生出加解密密钥
1)CryptAcquireContext
- 返回CSP句柄,参数设置与摘要运算时一致。
2)CryptCreateHash
- 生成摘要运算对象。
3)CryptHashData
- 生成摘要。pbData为调用加密功能的上位程序输入的加密口令。
9.对称解密
对称解密与加密相对应,调用顺序和参数设置基本一致。
-
CryptAcquireContext CryptCreateHash CryptHashData CryptDeriveKey CryptSetKeyParam BOOL CryptDecrypt( HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen )
二、PKCS#11:
在密码系统中,PKCS#11是公钥加密标准(PKCS, Public-Key Cryptography Standards)中的一份子 ,由RSA实验室(RSA Laboratories)发布[1],它为加密令牌定义了一组平台无关的API ,如硬件安全模块和智能卡。
PKCS#11标准定义了与密码令牌(如硬件安全模块(HSM)和智能卡)的独立于平台的API,并将API本身命名为“Cryptoki”(来自“加密令牌接口”,发音为“crypto-key” - 但是“PKCS#11”通常用于指代API以及定义它的标准)。 API定义了最常用的加密对像类型(RSA密钥,X.509证书,DES / 三重DES密钥等)以及使用,创建/生成,修改和删除这些对象所需的所有功能。
PKCS# 11标准定义了与密码令牌(如硬件安全模块(HSM)和智能卡)的独立于平台的API,API定义了最常用的加密对像类型(RSA密钥,X.509证书,DES / 三重DES密钥等)以及使用,创建/生成,修改和删除这些对象所需的所有功能。
PKCS#11创建和支持下列对象:
接口指令:
| 接口类型 | 函数名称 | 描述 |
|---|---|---|
| 通用接口函数 | C_Initialize | 初始化 Cryptoki |
| C_Finalize | 整理各种适合 Cryptoki的资源 | |
| C_GetInfo | 获得关于Cryptoki的通用信息 | |
| C_GetFunctionList | 获得Cryptoki 库函数的进入点 | |
| 槽和令牌管理函数 | C_GetSlotList | 获得系统中槽的名单 |
| C_GetSlotInfo | 获得关于特殊槽的信息 | |
| C_GetTokenInfo | 获得关于特殊令牌的信息 | |
| C_WaitForSlotEvent | 等待槽事件(令牌插入,转移等) 的发生 | |
| C_GetMechanismList | 获得由令牌支持的机制的名单 | |
| C_GetMechanismInfo | 获得关于特殊机制的信息 | |
| C_InitToken | 初始化一个令牌 | |
| C_InitPIN | 初始化普通用户的 PIN | |
| C_SetPIN | 改变现在用户的PIN | |
| 会话管理函数 | C_OpenSession | 打开一个应用程序和特殊令牌之间的连接或安装一个应用程序呼叫返回令牌插入 |
| C_CloseSession | 关闭一个会话 | |
| C_CloseAllSessions | 用令牌关闭所有的会话 | |
| C_GetSessionInfo | 获得关于会话的信息 | |
| C_GetOperationState | 获得会话的加密操作状态 | |
| C_SetOperationState | 设置会话的加密操作状态 | |
| C_Login | 注册一个令牌 | |
| C_Logout | 从一个令牌注销 | |
| 对象管理函数 | C_CreateObject | 建立一个对象 |
| C_CopyObject | 建立一个对象的拷贝 | |
| C_DestroyObject | 销毁一个对象 | |
| C_GetObjectSize | 获取字节中一个对象的大小 | |
| C_GetAttributeValue | 获取一个对象的属性值 | |
| C_SetAttributeValue | 改变一个对象的属性值 | |
| C_FindObjectsInit | 初始化一个对象的搜索操作 | |
| C_FindObjects | 继续一个对象搜索操作 | |
| C_FindObjectsFinal | 完成一个对象搜索操作 | |
| 加密函数 | C_EncryptInit | 初始化一个加密操作 |
| C_Encrypt | 加密单部分数据 | |
| C_EncryptUpdate | 继续一个多部分加密操作 | |
| C_EncryptFinal | 完成一个多部分加密操作 | |
| 解密函数 | C_DecryptInit | 初始化一个解密操作 |
| C_Decrypt | 解密单部分加密数据 | |
| C_DecryptUpdate | 继续一个多部分解密操作 | |
| C_DecryptFinal | 完成一个多部分解密操作 | |
| 消息解密函数 | C_DigestInit | 初始化一个消息摘要操作 |
| C_Digest | 摘要单部分数据 | |
| C_DigestUpdate | 继续一个多部分摘要操作 | |
| C_DigestKey | 摘要一个密钥 | |
| C_DigestFinal | 完成一个多部分摘要操作 | |
| 签名和消息鉴别函数 | C_SignInit | 初始化一个签名操作 |
| C_Sign | 签名单部分数据 | |
| C_SignUpdate | 继续一个多部分签名操作 | |
| C_SignFinal | 完成一个多部分签名操作 | |
| C_SignRecoverInit | 初始化一个签名操作,在操作中数据能从签名中恢复 | |
| C_SignRecover | 签名单部分数据,在操作中数据能从签名中恢复 | |
| 签名鉴定消息鉴别函数 | C_VerifyInit | 初始化一个鉴定操作 |
| C_Verify | 在单部分数据上鉴定一个签名 | |
| C_VerifyUpdate | 继续一个多部分鉴定操作 | |
| C_VerifyFinal | 完成一个多部分鉴定操作 | |
| C_VerifyRecoverInit | 初始化一个鉴定操作,在操作中数据能从签名中恢复 | |
| C_VerifyRecover | 在单部分数据上鉴定一个签名,在操作中数据能从签名中恢复 | |
| 双效加密函数 | C_DigestEncryptUpdate | 继续类似的多部分摘要和加密操作 |
| C_DecryptDigestUpdate | 继续类似的多部分解密和摘要操作 | |
| C_SignEncryptUpdate | 继续类似的多部分签名和加密操作 | |
| C_DecryptVerifyUpdate | 继续类似的多部分解密和鉴定操作 | |
| 密钥管理函数 | C_GenerateKey | 产生一个保密密钥 |
| C_GenerateKeyPair | 产生一个公共/私钥对 | |
| C_WrapKey | 加密一个密钥 | |
| C_UnwrapKey | 解密一个密钥 | |
| C_DeriveKey | 从基础密钥派生一个密钥 | |
| 随机数生成函数 | C_SeedRandom | 把一个附加种子材料加入随机数字生成器 |
| C_GenerateRandom | 生成随机数 | |
| 并行功能管理函数 | C_GetFunctionStatus | 已废弃函数,返回CKR_FUNCTION_NOT_PARALLEL |
| C_CancelFunction | 已废弃函数,返回CKR_FUNCTION_NOT_PARALLEL |
CSP接口标准:
| 接口类型 | 函数名称 | 描述 |
|---|---|---|
| CSP连接函数 | CPAcquireContext | 为应用程序创建一个上下文 |
| CPGetProvParam | 返回CSP相关的信息 | |
| CPReleaseContext | 释放CPAcquireContext创建的上下文 | |
| CPSetProvParam | 设置CSP的参数操作 | |
| CSP密钥生成和交换函数 | CPDeriveKey | 从一个数据散列中生成一个会话密钥,它保证生成的密钥互不相同 |
| CPDestroyKey | 释放一个密钥句柄,释放后,句柄将无效,密钥将无法再被访问 | |
| CPExportKey | 从CSP容器中导出密钥 | |
| CPGenKey | 用来生成密钥或密钥对 | |
| CPGenRandom | 使用随机数填充一个缓冲 | |
| CPGetKeyParam | 用来得到加密操作密钥的属性 | |
| CPGetUserKey | 用来获取CSP容器中的持久密钥对 | |
| CPImportKey | 从一个blob中导入密钥到CSP容器中 | |
| CPSetKeyParam | 设置密钥的属性 | |
| CSP加解密函数 | CPDecrypt | 用来解密先前被加密的数据 |
| CPEncrypt | 用来加密明文 | |
| CSP散列和数字签名函数 | CPCreateHash | 初始化并散列输入数据 |
| CPDestroyHash | 删除一个散列对象句柄 | |
| CPDuplicateHash | 创建一个散列对象的拷贝 | |
| CPGetHashParam | 获取散列对象的计算结果 | |
| CPHashData | 散列输入的数据 | |
| CPSetHashParam | 定制一个散列对象的属性 | |
| CPSignHash | 签名一个散列对象 | |
| CPVerifySignature | 校验一个数字签名 |
三、GMT 0016-2012
*GMT 0016-2012:
本标准规定了基于PKI密码体制的智能密码钥匙密码应用接口,描述了密码应用接口的函数、数据类型、参数的定义和设备的安全要求。
本标准适用于智能密码钥匙产品的研制、使用和检测。
- 本标准规定了基于PKI密码体制的智能密码钥匙密码应用接口,描述了密码应用接口函数、数据类型、参数的定义和设备安全要求。
- 适用于智能密码钥匙产品的研制、使用和检测。
缩略语
| API | 应用编程接口(Application Programing Interface) |
|---|---|
| PKI | 公钥基础设施(Public Key Infrastructure) |
| PKCS#1 | 公钥密码使用标准系列规范中的第1部分,定义RSA公开密钥算法加密和签名机制(the Public-Key Cryptograhy Standard Part 1) |
| PKCS#5 | 公钥密码使用标准系列规范中的第5部分,描述一种利用从口令派生出来的安全密钥加密字符串的方法(the Public-Key Cryptograhy Standard Part 5) |
| PIN | 个人身份识别码(Personal Identification Number) |
| MAC | 消息鉴别码(Message Authentication Code) |
1. 签名验签
-
RSA签名
**
![]()
-
RSA验签
**
![]()
-
ECC签名
**
![]()
![]()
-
ECC验签
**
![]()
2. 加密
-
加密初始化
**
![]()
-
单组数据加密
**
![]()
-
多组数据加密
**
![]()
![]()
-
结束加密
**
![]()
3. 解密
-
解密初始化
**
![]()
-
单组数据解密
**
![]()
![]()
-
多组数据解密
**
![]()
-
结束解密
**
![]()
四、GMT 0018-2012
本标准规定了公钥密码基础设施应用技术体系下服务类密码设备的应用接口。
适用于服务类密码设备的研制、使用,以及基于该类密码设备的应用开发,也可用于指导该类密码设备的检测。
符号和缩略语
| ECC | 椭圆曲线算法(Elliptic Curve Cryptography) |
|---|---|
| IPK | 内部加密公钥(Internal Public Key) |
| ISK | 内部加密私钥(Internal Private Key) |
| EPK | 外部加密公钥(External Public Key) |
| KEK | 密钥加密密钥(Key Encrypt Key) |
密码服务
1. 对称算法
-
对称加密
**
![]()
-
对称解密
**
![]()
-
计算MAC
**

2. 非对称算法
-
外部公钥RSA运算
**
![]()
-
内部公钥RSA运算
**
![]()
-
内部私钥RSA运算
**
![]()
代码链接如下:https://gitee.com/drewlff/experiment-1/issues/I53XBM
实现截图如下:






















浙公网安备 33010602011771号