Crypto API
0 查找各种标准的原始文档,研究学习
- 作为一部分 Microsoft Windows 提供的应用程序编程接口 (API),CryptoAPI 提供了一组函数。这些函数允许应用程序在对用户的敏感私钥数据提供保护时,以灵活的方式对数据进行加密或数字签名。实际的加密操作是由称为加密服务提供程序 (CSP) 的独立模块执行。
- CryptoAPI是一组函数,为了完成数学计算,必须具有密码服务提供者模块(CSP)。Microsoft通过捆绑RSA Base Provider在操作系统级提供一个CSP,使用RSA公司的公钥加密算法,更多的CSP可以根据需要增加到应用中。事实上,CSP有可能与特殊硬件设备(如智能卡)一起来进行数据加密。CryptoAPI接口允许简单的函数调用来加密数据,交换公钥,散列一个消息来建立摘要以及生成数字签名。它还提供高级的管理操作,如从一组可能的CSP中使用一个CSP。此外,CryptoAPI还为许多高级安全性服务提供了基础,包括用于电子商务的SET,用于加密客户机/服务器消息的PCT,用于在各个平台之间来回传递机密数据和密钥的PFX,代码签名等等。
- CryptoAPI体系架构共由五大主要部分组成:基本CSP函数、证书编解码函数、证书库管理函数、简单消息函数、底层消息函数。其结构图如下图所示。
1 总结在编程中的使用方式
- 实现用crypto API加密解密可以用下列流程图进行大概的描述。
- 使用CryptoAPI编写一个文件保护程序,具有如下功能:
- (1)给定明文文件,生成加密文件,同时产生文件的数字签名文件;
- (2)给定密文文件,解密出明文文件,并验证签名的正确性。
- 在不安全的网络上进行安全的数据传输涉及三个方面的要求:信息隐藏,身份鉴别和完整性检验。CryptoAPI除了提供上述三个功能外还提供标准的ASN.1编码、解码,信息解密,数字证书和证书存储区的管理,证书信任列表、吊销列表和证书有效性检查等功能。
- 信息隐藏的意义是保障信息内容只能被特定的人获取。信息隐藏通常是使用某种形式的密码学方式。数据加密算法能保障信息的安区隐藏和传输。数据加密算法是将明文数据经过一定的变换使其看上去是一组毫无意义的数据。在没有加密密钥的情况下,对于好的加密算法想从密文获取明文信息是不可能的。被加密的数据可以是任意的ASCII编码文本文件,数据库文件,和任意需要进行安全传输的数据。这里,“信息”是指任意的一段数据,“明文”是指任意一段没有被加密的数据,“密文”是指任意一段加密的数据。被加密的数据可以在不安全的通道上进行传输而不伤害其安全性。之后,密文可以被还原成明文。数据加密和解密的概念是:对数据加密的时候需要一个加密密钥,相当于门上的一把钥匙。解密的时候,需要使用一个解密密钥来解开数据。加密密钥、解密密钥可以相同也可以不相同。加密密钥必须小心保存,给其它用户的时候也必须通过安全的通道传递。对解密密钥的访问权限必须小心控制,因为拥有解密密钥意味着可以解开所有相应加密密钥加密的信息。
- 安全通讯的前提是通讯的双方知道对方的身份。身份鉴别的任务就是鉴别一个用户或者实体的真实身份。标识用户身份的文档通常被称为信任状或者凭证。身份鉴别有时候也用来判定接受的数据就是被发送的数据。如果A向B发送了一段数据,B需要鉴别这段数据就是A发出去的,而不是其它冒充A发出去的。为了满足这类验证的需求,CryptoAPI提供数字签名和校验函数,用来对信息进行鉴别。因为在计算机网网络上传输的数据与用户之间并没有物理连接,因此对数据进行鉴别的凭证也必须能够在网络上进行传输。这种凭证必须由受信任的凭证发行机构发行。数字证书就是平常说的证书就是这种凭证,是计算机在网络上进行身份验证的有效凭证。数字证书是由一个被称为证书机构的信任组织或实体颁发的凭证。它包含与证书对应的用户公钥以及其它一些记录证书主题和用户信息的数据。证书机构只有在验证了证书主题和证书对应的用户公钥的有效性之后才会签发证书。证书申请者和证书机构之间交换签发证书信息可以使用物理介质,比如软盘,进行传输。通常,这种信息都是在计算机网络上进行完成的。证书机构使用被信任的服务程序处理用户的请求和证书的签发工作。
- 任何通过不安全介质传输的信息都可以被意外或蓄意的修改。在现实世界中,盖章、签名就是用来提供和证明信息完整性的工具。信息的接收者不但需要确定信息是由谁发送的,还要确定自己收到的信息是发送者发送的信息,而没有任何的变化。要建立数据的完整性检测机制,不仅要发送信息本身,还要发送用来校验数据的信息,这一信息通常被称作哈希值。数据和验证信息都可以与数字签名一起发送来证明其完整性。
- 代码示例
创建密钥容器,得到CSP句柄
if(CryptAcquireContext(
&hCryptProv, // 返回CSP句柄
UserName, // 密码容器名
NULL, // NULL时使用默认CSP名(微软RSA Base Provider)
PROV_RSA_FULL, // CSP类型
0)) // Flag values
{
//以UserName为名的密钥容器存在,那么我们已经得到了CSP的句柄
printf("A crypto context with the %s key container /n", UserName);
printf("has been acquired./n/n");
}
else //如果密钥容器不存在,我们需要创建这个密钥容器
{
if(CryptAcquireContext(
&hCryptProv,
UserName,
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET)) //创建以UserName为名的密钥容器
{
//创建密钥容器成功,并得到CSP句柄
printf("A new key container has been created./n");
}
else
{
HandleError("Could not create a new key container./n");
}
} // End of else`
`CryptAcquireContext(&hCryptProv,
userName,
NULL,
PROV_RSA_FULL,
CRYPT_DELETEKEYSET);
文件加解密和签名验签
(1)打开源文件
hSource = fopen(szSource,"rb")
(2)取得密钥容器(CSP)句柄
CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,0)
(3)根据用户输入的密码创建一个会话密钥(即对称密钥,用于对原文件加密)
CryptCreateHash(hCryptProv,CALG_MD5, 0, 0, &hHash)//创建一个Hash对象
CryptHashData(hHash, (BYTE *)szPassword, strlen(szPassword), 0)//用用户输入的密码产生一个散列
CryptDeriveKey(hCryptProv, ENCRYPT_ALGORITHM,hHash, KEYLENGTH, &hKey))//通过散列生成一个会话密钥
CryptDestroyHash(hHash);//销毁Hash对象
(4)加密数据文件
CryptEncrypt(
hKey, // 密钥
0, // 如果数据同时进行散列和加密,这里传入一个散列对象
feof(hSource), // 如果是最后一个被加密的块,输入 TRUE. 如果不是输
// 入 FALSE 这里通过判断是否到文件尾来决定是否为最后一块
0, // 保留
pbBuffer, // 输入被加密数据,输出加密后的数据
&dwCount, // 输入被加密数据实际长度,输出加密后数据长度
dwBufferLen) //pbBuffer 的大小
(5)清理工作,如释放Buffer空间、密钥句柄、CSP句柄等。
if(pbBuffer)
free(pbBuffer);
if(hKey)
CryptDestroyKey(hKey);
if(hHash)
CryptDestroyHash(hHash);
if(hCryptProv)
CryptReleaseContext(hCryptProv, 0);
.....
解密文件
(1)打开加密文件(同上)
(2)取得密钥容器(CSP)句柄(同上)
(3)根据用户输入的密码创建一个会话密钥(即对称密钥,用于对原文件解密)(同上)
(4)解密数据文件
CryptDecrypt(
hKey, // 密钥
0, // 如果数据同时进行散列和加密,这里传入一个散列对象
feof(hSource), // 如果是最后一个被加密的块,输入 TRUE. 如果不是输 .
// 入 FALSE 这里通过判断是否到文件尾来决定是否为最后一块。
0, // 保留
pbBuffer, // 输入被加密数据,输出加密后的数据
&dwCount)) // 输入被加密数据实际长度,输出加密后数据长度
(5)清理工作,如释放Buffer空间、密钥句柄、CSP句柄等。(同上)
签名文件
(1)打开源文件(同上)
(2)取得密钥容器(CSP)句柄(同上)
(3)取得签名用的密钥句柄(非对称RSA密钥)
CryptGetUserKey(
hCryptProv, // 我们已经得到的 CSP 句柄
AT_SIGNATURE, // 这里想得到 signature key pair
&hKey)) // 返回密钥句柄
(4)导出签名用密钥对的公钥,保存在pbKeyBlob中
CryptExportKey(hKey, NULL,PUBLICKEYBLOB, 0, pbKeyBlob,&dwBlobLen)
(5)计算数据文件的Hash值,保存在Hash对象hHash中
CryptCreateHash(hCryptProv,CALG_MD5,0,0,&hHash)//生成一个空的Hash对象
CryptHashData(hHash,pbBuffer,dwCount,0)//计算数据文件的Hash值,保存在Hash对象中
(6)对数据文件的Hash值进行签名,数字签名保存在pbSignature中
CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pbSignature, &dwSigLen)
(7)清理工作,如释放Buffer空间、密钥句柄、CSP句柄等。(同上)
验签文件
(1)打开文件(同上)
(2)取得密钥容器(CSP)句柄(同上)
(3)导入 pbKeyBlob 公钥
CryptImportKey(hCryptProv, pbKeyBlob, dwBlobLen, 0, 0, &hPubKey)
(4)计算数据文件的Hash值,保存在Hash对象hHash中。(同上)
(5)验证数字签名
CryptVerifySignature(hHash, pbSignature, dwSigLen,hPubKey,NULL, 0)
(6)清理工作,如释放Buffer空间、密钥句柄、CSP句柄等。(同上)
2 列出包含的函数,进行分类,并总结异同
- 服务提供者函数
应用程序使用服务提供者函数来连接和断开一个CSP。
函数名 |
描述 |
CryptAcquireContext |
获得指定CSP的密钥容器的句柄 |
CryptContextAddRef |
对HCRYPTPROV句柄增加一个应用计数 |
CryptEnumProviders |
枚举当前计算机中的CSP |
CryptEnumProviderTypes |
枚举CSP的类型 |
CryptGetDefaultProvider |
对于指定CSP类型的缺省CSP |
CryptGetProvParam |
得到一个CSP的属性 |
CryptInstallDefaultContext |
安装先前得到的HCRYPTPROV上下文作为当前缺省的上下文 |
CryptReleaseContext |
释放由CryptAcquireContext得到的句柄 |
CryptSetProvider和CryptSetProviderEx |
为指定CSP类型指定一个缺省的CSP |
CryptSetProvParam |
指定一个CSP的属性 |
CryptUninstallDefaultContext |
删除先前由CryptInstallDefaultContext安装的缺省上下文 |
- 密钥的产生和交换函数
密钥产生函数创建、配置和销毁加密密钥。他们也用于和其他用户进行交换密钥。
CryptAcquireCertificatePrivateKey |
对于指定证书上下文得到一个HCRYPTPROV句柄和dwKeySpec |
CryptDeriveKey |
从一个密码中派生一个密钥 |
CryptDestoryKey |
销毁密钥 |
CryptDuplicateKey |
制作一个密钥和密钥状态的精确复制 |
CryptExportKey |
把CSP的密钥做成BLOB 传送到应用程序的内存空间中 |
CryptGenKey |
创建一个随机密钥 |
CryptGenRandom |
产生一个随机数 |
CryptGetKeyParam |
得到密钥的参数 |
CryptGetUserKey |
得到一个密钥交换或签名密钥的句柄 |
CryptImportKey |
把一个密钥BLOB传送到CSP 中 |
CryptSetKeyParam |
指定一个密钥的参数 |
- 编码/解码函数
有一些编码/解码函数,他们可以用来对证书、证书撤销列表、证书请求和证书扩展进行编码和解码。
CryptDecodeObject |
对lpszStructType结构进行解码 |
CryptDecodeObjectEx |
对lpszStructType结构进行解码,此函数支持内存分配选项 |
CryptEncodeObject |
对lpszStructType结构进行编码 |
CyptEncodeObjectEx |
对lpszStructType结构进行编码,此函数支持内存分配选项 |
- 数据加密/解密函数
这些函数支持数据的加密/解密操作。
CryptEncrypt 和CryptDecrypt |
要求在被调用前指定一个密钥。这个密钥可以由CryptGenKey、CryptDeriveKey 或CryptImportKey 产生。创建密钥时要指定加密算法。 |
CryptSetKeyParam函数 |
可以指定额外的加密参数。 |
CryptDecrypt |
使用指定加密密钥来解密一段密文 |
CryptEncrypt |
使用指定加密密钥来加密一段明文 |
CryptProtectData |
执行对DATA_BLOB结构的加密 |
CryptUnprotectData |
执行对DATA_BLOB结构的完整性验证和解密 |
- 哈希和数字签名函数
这些函数在应用程序中完成计算哈希、创建和校验数字签名。
CryptCreateHash |
创建一个空哈希对象 |
CryptDestoryHash |
销毁一个哈希对象 |
CryptDuplicateHash |
复制一个哈希对象 |
CryptGetHashParam |
得到一个哈希对象参数 |
CryptHashData |
对一块数据进行哈希,把它加到指定的哈希对象中 |
CryptHashSessionKey |
对一个会话密钥进行哈希,把它加到指定的哈希对象中 |
CryptSetHashParam |
设置一个哈希对象的参数 |
CryptSignHash |
对一个哈希对象进行签名 |
CryptVerifySignature |
校验一个数字签名 |
- 证书库函数
一个用户站点可以收集许多证书。这些证书是为这个站点的用户所使用的,证书描述了这个用户的具体身份。对于每个人,可能有一个以上的证书。证书库和其相关的函数提供了对库获得、枚举、验证和使用证书库里的信息。
CertAddStoreToCollection |
在证书库中增加一个证书 |
CertCloseStore |
关闭一个证书库句柄 |
CertControlStore |
如果证书缓冲区和证书本身内容不相符时,允许给应用程序发一个通知 |
CertDuplicateStore |
通过增加引用计数来复制证书库句柄 |
CertEnumPhysicalStore |
对于指定系统库枚举物理库 |
CertEnumSystemStore |
枚举所有可用的系统库 |
CertEnumSystemStoreLocation |
枚举可用系统库的所有位置 |
CertGetStoreProperty |
得到一个库的属性 |
CertOpenStore |
使用指定库类型来打开证书库 |
CertOpenSystemStore |
打开一个系统证书库 |
CertRegisterPhysicalStore |
在一个注册系统库里增加一个物理库 |
CertRegisterSystemStore |
注册一个系统库 |
CertRemoveStoreFromCollection |
从一个库集合里删除证书库 |
CertSaveStore |
保存证书库 |
CertSetStoreProperty |
设置证书属性 |
CertUnregisterPhysicalStore |
从系统库中删除一个物理库 |
CertUnregisterSystemStore |
反注册一个指定系统库 |
3 以龙脉GM3000Key为例,写出调用不同接口的代码,把运行截图加入博客,并提供代码链接
- 运行截图
- 代码链接:
C:\Users\周睿雅\Downloads\龙脉密码钥匙驱动实例工具等\mToken-GM3000\csp\samples\CryptAPI\VC\EncryptDecryptFile\EncryptFile.sln
C:\Users\周睿雅\Downloads\龙脉密码钥匙驱动实例工具等\mToken-GM3000\csp\samples\CryptAPI\VC\EnumCerts\EnumCerts.sln
PKCS#11
0 查找各种标准的原始文档,研究学习
- 在密码系统中,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密钥等)以及使用,创建/生成,修改和删除这些对象所需的所有功能。
1 总结在编程中的使用方式
- 框架
- 会话状态
- 对象
- C_Initialize()语法中,pInitArgs 是空值 NULL_PTR 或是指向 CK_C_INITIALIZE_ARGS 结构的指针。通过 NULL_PTR,该库可以将 Oracle Solaris 互斥锁用作锁定原语,在多个线程之间仲裁对内部共享结构的访问。请注意,Oracle Solaris 加密框架不接受互斥锁。由于 cryptoki 库的此实现可以安全高效地处理多线程,因此建议使用 NULL_PTR。应用程序还可以使用 pInitArgs 来设置诸如 CKF_LIBRARY_CANT_CREATE_OS_THREADS 之类的标志。C_Finalize() 表示应用程序使用 PKCS #11 库结束会话。
- C_GetSlotList() 使用的是可用插槽的列表。如果除了 pkcs11_softtoken.so 以外尚未安装任何其他加密提供者,则 C_GetSlotList() 仅返回缺省插槽。如果 tokenPresent 设置为 TRUE,则会将搜索限制在那些存在令牌的插槽。如果 pSlotList 设置为 NULL_PTR,则 C_GetSlotlist() 仅返回插槽的数量。pulCount是指向用于接收插槽计数的位置的指针。如果 pSlotList 指向用于接收插槽的缓冲区,则 pulCount 将设置为 CK_SLOT_ID 元素的最大预期数量。在返回时,pulCount 将设置为 CK_SLOT_ID 元素的实际数量。通常,PKCS #11应用程序会调用 C_GetSlotList() 两次。第一次调用 C_GetSlotList() 用于获取进行内存分配的插槽数量,第二次调用 C_GetSlotList() 用于检索插槽。
- C_GetMechanismList() 用于获取指定令牌所支持的机制类型的列表。slotID 用于标识令牌的插槽。pulCount 是指向用于接收机制数量的位置的指针。如果 pMechanismList 设置为 NULL_PTR,则 *pulCount 将返回机制的数量。否则,必须将 *pulCount 设置为列表的大小,pMechanismList 必须指向用于存放列表的缓冲区。
- 代码示例
初始化 PKCS #11 库
C_Initialize(CK_VOID_PTR pInitArgs);
可用插槽的列表
C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount);
获取指定令牌
C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount);
2 列出包含的函数,进行分类,并总结异同
- PKCS #11标准颁发了70余条指令。其中部分指令简介如下表:
接口类型 |
函数名称 |
描述 |
通用接口函数 |
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接口标准为微软所颁发,在windows操作系统上通行。CSP中重要的概念是容器,一个容器中具有一对公私钥。而证书却是这一对密钥的附加属性了。CSP总共有23个函数接口。简介如下:
接口类型 |
函数名称 |
描述 |
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 |
校验一个数字签名 |
3 以龙脉GM3000Key为例,写出调用不同接口的代码,把运行截图加入博客,并提供代码链接
- 运行截图
- 代码链接:
C:\Users\周睿雅\Downloads\龙脉密码钥匙驱动实例工具等\mToken-GM3000\pkcs11\windows\samples\PKCStest\PKCStest.sln
C:\Users\周睿雅\Downloads\龙脉密码钥匙驱动实例工具等\mToken-GM3000\pkcs11\windows\samples\GetUSBInfos\getusbinfos.sln
GMT 0016-2012
0 查找各种标准的原始文档,研究学习
- 本标准规定了基于PKI密码体制的智能密码钥匙密码应用接口,描述了密码应用接口的函数、数据类型、参数的定义和设备的安全要求。
- 本标准适用于智能密码钥匙产品的研制、使用和检测。
1 总结在编程中的使用方式
- 智能密码钥匙密码应用接口位于智能密码钥匙应用程序与设备之间,下图所示为层次关系。
- 一个设备中存在设备认证密钥和多个应用,应用之间相互独立。设备的逻辑结构如下图所示。
- 下列文件对于本文件的应用是必不可少的凡是注日期的引用文件,仅注日期的版本适用于本文件。凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于本文件。(1)GM/T 0006 密码应用标识规范(2)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)
2 列出包含的函数,进行分类,并总结异同
- 设备管理系列函数
- 访问控制系列函数
- 应用管理系列函数
- 文件管理系列函数
- 容器管理系列函数
- 密码服务系列函数
3 以龙脉GM3000Key为例,写出调用不同接口的代码,把运行截图加入博客,并提供代码链接
GMT 0018-2012
0 查找各种标准的原始文档,研究学习
- 本标准规定了公钥密码基础设施应用技术体系下服务类密码设备的应用接口标准。
- 本标准适用于服务类密码设备的研制使用,以及基于该类密码设备的应用开发,也可用于指导该类密码设备的检测
1 总结在编程中的使用方式
- 规范性引用文件下列文件对于本文件的应用是必不可少的。凡是注日期的引用文件,仅注日期的版本适用于本文件,凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于本文件。(1)GM/T0006密用标识规范 (2)GM/T0009SM2密码算法使用规范。
- 在公钥密码基础设施应用技术体系框架中,密码设备服务层由密码机,密码卡,智能密码终端等设备组成,通过本标准规定的密码设备应用接口向通用密码服务层提供基础密码服务。如下图所示。
- 术语和定义
- 算法标识algorithm ideutifier:用于对密码算法进行唯一标识的符号。
- 非对称密码算法/公钥密码算法 asymmetric cryptographic algorithm/public key cryptographic algorithm加解密使用不同密钥的密码算法。
- 解密decipherment/decryption:加密过程对应的逆过程。
- 设备密钥device key pair:存储在设备内部的用于设备管理的非对称密钥对包含签名密钥对和加密密钥对。
- 加密encipherment/encryption:对数据进行密码变换以产生密文的过程。
- 密钥加密密钥key encrypt key:KEK对密钥进行加密保护的密钥。
- 公钥基础设施public keyinfrastructure:PKI用公钥密码技术建立的普遍适用的基础设施,为用户提供证书管理和密钥管理等安全服务。
- 私钥访问控制码private key access password:用于验证私钥使用权限的口令字。
- 对称密码技术/对称密码体制symmetric cryptographic technique:原发者和接收者均采用同秘密密钥进行变换的密码技术(体制)。其中,加密密钥与解密密钥相同或者一个密钥可以从另一个密钥导出的密码体制。
- 会话密钥session key:处于层次化密钥结构中的最低层,仅在一次会话中使用的密钥。
- 用户密钥user key:存储在设备内部的用于应用密码运算的非对称密钥,包含签名密钥对和加密密钥对。
- 缩略语
- ECC 椭圆曲线算法(Elliptic Curve Cryptography)
- IPK 内部加密公钥(Internal Public Key)
- ISK 内部加密私钥(Interal Private Key)
- EPK 外部加密公钥(Extenal Public Key)
- KEK 密钥加密密钥(Key Encrypt Key)
2 列出包含的函数,进行分类,并总结异同
- 设备管理类函数
打开设备:SDF_OpenDevice
关闭设备:SDF_CloseDevice
创建会话:SDF_OpenSession
关闭会话:SDF_CloseSession
获取设备信息:SDF_GetDeviceInfo
产生随机数:SDF_GenerateRandom
获取私钥使用权限:SDF_GetPrivateKeyAccessRight
- 密钥管理类函数
导出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_GenerateKeyWithECC
产生协商数据并计算会话密钥:SDF_GenerateAgreementDataAndKeyWithECC
基于ECC算法的数字信封转换:SDF_ExchangeDigitEnvelopeBaseOnECC
生成会话密钥并用密钥加密密钥加密输出:SDF_GenerateKeyWithKEK
导入会话密钥并用密钥加密密钥解密:SDF_ImportKeyWithKEK
导入明文会话密钥:SDF_ImportKey
销毁会话密钥:SDF_DestroyKey
释放私钥使用权限:SDF_ReleasePrivateKeyAccessRight
- 非对称算法运算类函数
外部公钥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
- 对称算法运算类函数
对称加密:SDF_Encrypt
对称解密:SDF_Decrypt
计算MAC:SDF_CalculateMAC
- 杂凑运算类函数
杂凑运算初始化:SDF_HashInit
多包杂凑运算:SDF_HashUpdate
杂凑运算结束:SDF_HashFinal
- 用户文件操作类函数
创建文件:SDF_CreateFile
读取文件:SDF_ReadFile
写文件:SDF_WriteFile
删除文件:SDF_DeleteFile
3 以龙脉GM3000Key为例,写出调用不同接口的代码,把运行截图加入博客,并提供代码链接
- 运行截图
- 代码链接:
C:\Users\周睿雅\Downloads\龙脉密码钥匙驱动实例工具等\mToken-GM3000\skf\samples\windows\EncryptData\EncryptData.sln