密码引擎的设计与实现
一、任务一
- 安装Ubuntu和OpenEuler虚拟机
- 下载最新的OpenSSL源码(1.1版本)
- 用自己的8位学号建立一个文件夹,cd 你的学号,用pwd获得绝对路径
- 参考https://www.cnblogs.com/rocedu/p/5087623.html先在Ubuntu中完成OpenSSL编译安装,然后在OpenEuler中重现
./config --prefix=..(学号目录的绝对路径)指定OpenSSL编译链接 - 提交 test_openssl.c 编译运行截图
- 加分项:在Windows中编译OpenSSL,记录编译过程,提交相关文档(推荐MarkDown格式)
Ubuntu中完成
代码:
#include <stdio.h>
#include <openssl/evp.h>
int main(){
OpenSSL_add_all_algorithms();
return 0;
}
命令:
./config --prefix=……
gcc -o to test_openssl.c -L/usr/local/ssl/lib -lcrypto -ldl -lpthread
执行./to;echo $?,结果打印0
OpenEuler中重现
在Windows中编译OpenSSL
1.安装win64-openssl
2.编译链接静态库
3.编译链接动态库
4.链接头文件
至此,部署完成。
二、任务二
0 参考附件中的视频
1 解压"资源"中“龙脉密码钥匙驱动实例工具等”压缩包
2 在Ubuntu中运行 “龙脉密码钥匙驱动实例工具等\mToken-GM3000\skf\samples\linux_mac”中例程,提交运行结果截图
3 加分项:运行“龙脉密码钥匙驱动实例工具等\mToken-GM3000\skf\samples\windows”中例程,提交运行结果截图
在Ubuntu中运行龙脉密码钥匙驱动实例工具
加分项
三、任务三
密码引擎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,PKCS#11,GMT 0016-2012,GMT 0018-2012)
Crypto API
Windows CryptoAPI是Microsoft 公司提出的安全加密应用服务框架,也是PKI推荐使用的加密 API。它提供了在Win32 环境下使用认证、编码、加密和签名等安全服务时的标准加密接口,用于增强应用程序的安全性与可控性。应用开发者可以在不了解复杂的加密机制和加密算法的情况下,简便、快速地开发出标准、通用和易于扩展的安全加密应用程序。CryptoAPI 提供的功能主要有:密钥管理、数据加密和解密、数字签名和验证、证书管理、可信根证书管理、数据编码和解码、数字证书编码和解码、PKCS#7 标准格式编码和解码等。现在CryptoAPI的最新版本为2.0版本。
1.CryptoAPI 系统体系结构
Crypto API学习链接: https://docs.microsoft.com/en-us/windows/win32/seccrypto/cryptography-functions
CryptoAPI由五个主要功能区域组成:
- 基本加密函数
- 用于连接到云解决方案提供商的上下文函数。 这些函数使应用程序能够按名称选择特定的云解决方案提供商,或选择可以提供所需功能类的特定云解决方案提供商。
- 用于生成和存储加密密钥的密钥生成函数。 完全支持更改 链接模式、 初始化向量和其他加密功能。
- 用于交换或传输密钥的密钥交换函数。
- 证书编码/解码函数
- 用于加密或解密数据的函数。 还支持哈希数据。
- 证书Microsoft Store函数
- 用于管理数字证书集合的函数。 有关详细信息,请参阅数字证书和证书Microsoft Store函数。
- 简化的消息函数
- 用于加密和解密消息和数据的函数。
- 用于对消息和数据进行签名的函数。
- 用于验证已接收消息和相关数据的签名的真实性的函数。
- 低级别消息函数
- 用于执行简化消息函数执行的所有任务的函数。低级别消息函数比简化的消息函数更灵活,但需要更多的函数调用。
2.RAS公司的PKCS#11标准:
PKCS#11学习链接:https://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html
-
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。
函数如下:
3.GMT 0016-2012 智能密码钥匙密码应用接口规范
GMT 0016-2012学习: http://www.gmbz.org.cn/main/viewfile/20180110020423162671.html
接口标准
GMT 0016-2012是国家规定的智能密码钥匙密码应用接口规范,规定了基于PKI密码体制的智能密码钥匙密码应用接口,描述了密码应用接口的函数、数据类型、参数的定义和设备的安全要求。适用于智能密码钥匙产品的研制、使用和检测。
规范性引用文件
下列文件对于本标准的应用是必不可少的。凡是注日期的引用文件。仅所注日期的版本适用于本文件;凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于本文件;GM/T 0006密码应用标识规范;GM/T AAAA SM2密码算法使用规范
其中还包括了对部分术语的规定:
函数如下:
设备管理系列函数
访问控制系列函数
应用管理系列函数
文件管理系列函数
容器管理系列函数
密码服务系列函数
4.GMT 0018-2012 智能密码钥匙密码应用接口规范
GMT 0018-2012学习链接: http://www.gmbz.org.cn/main/viewfile/20180110020642562680.html
接口标准
GMT 0018-2012标准规定了公钥密码基础设施应用技术体系下服务类密码设备的应用接口标准。适用于服务类密码设备的研制、使用,以及基于该类密码设备的应用开发,也可用于指导该类密码设备的检测。
规范性引用文件
下列文件对于本文件的应用是必不可少的。凡是注日期的引用文件,仅注日期的版本适用于本文件;凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于本文件;GM/T 0006密码应用标识规范;GM/T AAAA SM2密码算法使用规范。
其中还包括了对部分术语的规定:
函数与2016相似,这里只列出部分:
设备管理类函数
设备管理类函数包括以下具体函数:
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
5.总结异同
1、总结这些API在编程中的使用方式
- Crypto API 提供了一系列函数库,开发者可以直接调用这些函数来实现加密解密等操作。
- PKCS#11 提供了一个通用的接口,让开发者可以通过这个接口调用各种不同厂商的密码设备。
- GMT 0016-2012 和 GMT 0018-2012 定义了一套标准的密码设备应用接口规范,开发者可以按照这个规范来编写代码,并调用相应的函数库实现各种操作。
2、列出这些API包含的函数,进行分类,并总结它们的异同
由于这些API设计的函数过多,前文已经总结过了,这里就只挑选部分函数进行展示。
Crypto API:
密钥生成:CryptGenKey()
密钥销毁:CryptDestroyKey()
加密:CryptEncrypt()
解密:CryptDecrypt()
PKCS#11:
初始化:C_Initialize()
签名:C_Sign()
检查机制是否可用:C_MechanismInfo()
对称密钥生成:C_GenerateKey()
密码设备信息获取:C_GetInfo()
GMT 0016-2012:
打开设备:SKF_OpenDevice()
创建会话:SKF_CreateApplication()
身份认证:SKF_Login()
获取设备信息:SKF_GetDeviceInfo()
密钥对生成:SKF_GenRandomKeyPair()
GMT 0018-2012:
设备初始化:SCD_Init()
打开设备:SCD_Open()
读卡:SCD_Read()
写卡:SCD_Write()
密钥生成:SDF_GenerateKey()
3、总结:
- Crypto API 和 PKCS#11 都是通用的密码操作接口,提供了一些基本的加解密操作和密钥生成等操作。
- GMT 0016-2012 和 GMT 0018-2012 则是更具体的密码设备应用接口规范,定义了更多的操作功能。
- 具体的函数名称和参数也有所不同,但基本功能类似。
以龙脉GM3000Key为例,写出调用不同接口的代码(Crypto API,PKCS#11,SKF接口),把运行截图加入博客,并提供代码链接
SKF接口
1.龙脉密码钥匙驱动实例工具等\mToken-GM3000\skf\samples\windows\EncryptData\EncryptData.sln
#include "../../include/skfapi.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Win32Dlg.h"
#define TRUE 1
#define FALSE 0
#define ERROR_THROW(r) {if((r) != SAR_OK) goto END_OF_FUN;}
#pragma comment(lib, "../../lib/mtoken_gm3000.lib")
void main()
{
ULONG ulRslt = SAR_OK;
HANDLE hdev = NULL;
HANDLE happ = NULL;
HANDLE hcont = NULL;
HANDLE hkey = NULL;
char szDevName[256] = {0};
char szAppName[256] = {0};
char szContName[256] = {0};
char pUserPin[64] = {'0', '1', '2', '3', '4', '5', '6', '\0'};
ULONG ulDevNameLen = 256;
ULONG ulAppNameLen = 256;
ULONG ulContNameLen = 256;
ULONG ulRetryCount = 0;
BYTE pbData[2048] = {0};
BYTE pbEncryptedData[2048] = {0};
BYTE *pbEncrypted_ptr = pbEncryptedData;
ULONG ulEncryptedDataLen = 2048;
ECCPUBLICKEYBLOB ecc_pub = {0};
PECCCIPHERBLOB pecc_cipher = NULL;
ULONG ulEccpubLen = sizeof(ECCPUBLICKEYBLOB);
BLOCKCIPHERPARAM bp = {0};
ulRslt = SKF_EnumDev(TRUE, szDevName, &ulDevNameLen);
ERROR_THROW(ulRslt)
char *pdevname = szDevName;
ulRslt = SKF_ConnectDev(pdevname, &hdev);
ERROR_THROW(ulRslt)
ulRslt = SKF_EnumApplication(hdev, szAppName, &ulAppNameLen);
ERROR_THROW(ulRslt)
char *pappname = szAppName;
ulRslt = SKF_OpenApplication(hdev, pappname, &happ);
ERROR_THROW(ulRslt)
{
CWin32Dlg dlg;
if(dlg.RegisterClass())
{
return ;
}
if(dlg.CreateInstance())
{
return ;
}
while(dlg.ProcessNextMessage())
{
}
memset(pUserPin, 0 , sizeof(pUserPin));
strncpy(pUserPin, dlg.GetPin(), 64);
}
ulRslt = SKF_VerifyPIN(happ, USER_TYPE, pUserPin, &ulRetryCount);
ERROR_THROW(ulRslt)
ulRslt = SKF_EnumContainer(happ, szContName, &ulContNameLen);
ERROR_THROW(ulRslt)
char *pcontname = szContName;
ulRslt = SKF_OpenContainer(happ, pcontname, &hcont);
ERROR_THROW(ulRslt)
//公钥从证书解析
ulRslt = SKF_ExportPublicKey(hcont, FALSE, (BYTE *)&ecc_pub, &ulEccpubLen);
ERROR_THROW(ulRslt)
//此处需要保存Cipher,解密时需要导入
pecc_cipher = (PECCCIPHERBLOB)malloc(sizeof(ECCCIPHERBLOB) + 64);
memset(pecc_cipher, 0, sizeof(ECCCIPHERBLOB) + 64);
ulRslt = SKF_ECCExportSessionKey(hcont, SGD_SM1_ECB, &ecc_pub, pecc_cipher, &hkey);
ERROR_THROW(ulRslt)
//根据加密模式设定IV
memcpy(bp.IV, "12345678", 8);
bp.IVLen = 8;
bp.PaddingType = 1;
ulRslt = SKF_LockDev(hdev, 0xFFFFFFFF);
ERROR_THROW(ulRslt)
ulRslt = SKF_EncryptInit(hkey, bp);
if(ulRslt != SAR_OK)
{
SKF_UnlockDev(hdev);
goto END_OF_FUN;
}
//分组计算时,SKF_EncryptUpdate每包数据长度为1024字节时,计算速度最快
ulRslt = SKF_EncryptUpdate(hkey, pbData, 1024, pbEncrypted_ptr, &ulEncryptedDataLen);
if(ulRslt != SAR_OK)
{
SKF_UnlockDev(hdev);
goto END_OF_FUN;
}
pbEncrypted_ptr += ulEncryptedDataLen;
ulEncryptedDataLen = 1024;
ulRslt = SKF_EncryptFinal(hkey, pbEncrypted_ptr, &ulEncryptedDataLen);
if(ulRslt != SAR_OK)
{
SKF_UnlockDev(hdev);
goto END_OF_FUN;
}
ulRslt = SKF_UnlockDev(hdev);
END_OF_FUN:
if(hkey != NULL)
SKF_CloseHandle(hkey);
if(hcont != NULL)
SKF_CloseContainer(hcont);
if(happ != NULL)
SKF_CloseApplication(happ);
if(hdev != NULL)
SKF_DisConnectDev(hdev);
if(pecc_cipher != NULL)
{
free(pecc_cipher);
pecc_cipher = NULL;
}
return ;
}
Crypto API接口
1.龙脉密码钥匙驱动实例工具等\mToken-GM3000\csp\samples\CryptAPI\VC\EncryptDecryptFile\EncryptFile.sln
#include "generic.h"
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool EncryptFile(const string &strSource,
const string &strDestination,
const string &strPassword);
//--------------------------------------------------------------------
// Begin main.
void main(void)
{
char szSrcFile[1024] = {0}; //sourcefile
char szTgtFile[1024] = {0}; //encryptfile
char szPassword[1024] = {0}; //password
printf("\nEncrypt a file.\n\nEnter the name of the file to be encrypt:\n");
scanf("%s", szSrcFile);
printf("Enter the name of the output file:\n");
scanf("%s", szTgtFile);
printf("Enter the password to encrypt the file:\n");
scanf("%s", szPassword);
if(EncryptFile(szSrcFile, szTgtFile, szPassword))
{
printf("Encrypt file successfully.\n");
}
else
{
printf("Encrypt file failed.\n");
}
}
//--------------------------------------------------------------------
// Code for the function EncryptFile called by main.
bool EncryptFile(const string &strSource,
const string &strDestination,
const string &strPassword)
{
//--------------------------------------------------------------------
// Declare and initialize local variables.
FILE *hSource = NULL;
FILE *hDestination = NULL;
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL;
HCRYPTHASH hHash = NULL;
//--------------------------------------------------------------------
// Open source file.
BeginAction("Open source file for read");
if(NULL != (hSource = fopen(strSource.c_str(), "rb")))
{
ActionSuccess();
}
else
{
ActionFailed(GetLastError());
return FALSE;
}
//--------------------------------------------------------------------
// Open destination file.
BeginAction("Open target file for write");
if(NULL != (hDestination = fopen(strDestination.c_str(), "wb")))
{
ActionSuccess();
}
else
{
ActionFailed(GetLastError());
return FALSE;
}
// Get a CSP handle.
BeginAction("CryptAcquireContext()");
if(CryptAcquireContext(&hCryptProv,
TEST_CONTAINER,
CSP_NAME,
PROV_RSA_FULL,
0))
{
ActionSuccess();
}
else // Container does not exists, let us create a new one.
{
ActionFailed(GetLastError());
BeginAction("CryptAcquireContext() CRYPT_NEWKEYSET");
if(CryptAcquireContext(&hCryptProv,
TEST_CONTAINER,
CSP_NAME,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
ActionSuccess();
}
else
{
ActionFailed(GetLastError());
return FALSE;
}
}
HCRYPTPROV_Holder holder(hCryptProv);
BeginAction("CryptCreateHash()");
if(CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))
{
ActionSuccess();
}
else
{
ActionFailed(GetLastError());
return FALSE;
}
BeginAction("CryptHashData()");
if(CryptHashData(hHash,
(BYTE *) strPassword.c_str(),
strPassword.length(),
0))
{
ActionSuccess();
}
else
{
ActionFailed(GetLastError());
return FALSE;
}
BeginAction("CryptDeriveKey()");
if(CryptDeriveKey(hCryptProv, ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey))
{
ActionSuccess();
}
else
{
ActionFailed(GetLastError());
return FALSE;
}
BeginAction("CryptDestroyHash()");
if(CryptDestroyHash(hHash))
{
hHash = NULL;
ActionSuccess();
}
else
{
ActionFailed(GetLastError());
return FALSE;
}
DWORD dwBlockLen = 0;
DWORD dwBufferLen = 0;
DWORD dwCount = 0;
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
//--------------------------------------------------------------------
// Determine the block size. If a block cipher is used,
// it must have room for an extra block.
if(ENCRYPT_BLOCK_SIZE > 1)
{
dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
}
else
{
dwBufferLen = dwBlockLen;
}
vector<BYTE> pbBuffer;
pbBuffer.resize(dwBufferLen);
//--------------------------------------------------------------------
// In a do loop, encrypt the source file and write to the source file.
do
{
//--------------------------------------------------------------------
// Read up to dwBlockLen bytes from the source file.
dwCount = fread(&pbBuffer[0], 1, dwBlockLen, hSource);
if(ferror(hSource))
{
ShowSysError("Read plain text", GetLastError());
return FALSE;
}
//--------------------------------------------------------------------
// Encrypt
if(!CryptEncrypt(hKey,
0,
feof(hSource), //file end
0,
&pbBuffer[0], // [in] sourcefile; [out] encryptdata
&dwCount, //encryptdatalength
dwBufferLen)) // encrypt data length
{
ShowSysError("CryptEncrypt()", GetLastError());
return FALSE;
}
//--------------------------------------------------------------------
// Write data to the destination file.
fwrite(&pbBuffer[0], 1, dwCount, hDestination);
if(ferror(hDestination))
{
ShowSysError("Write cipher text", GetLastError());
return FALSE;
}
}
while(!feof(hSource));
//--------------------------------------------------------------------
// End the do loop when the last block of the source file has been
// read, encrypted, and written to the destination file.
//--------------------------------------------------------------------
// Close files.
if(hSource)
{
fclose(hSource);
}
if(hDestination)
{
fclose(hDestination);
}
if(hKey)
{
CryptDestroyKey(hKey);
}
return TRUE;
} // End of Encryptfile
2.龙脉密码钥匙驱动实例工具等\mToken-GM3000\csp\samples\CryptAPI\VC\EnumCerts\EnumCerts.sln
#include <windows.h>
#include <wincrypt.h>
#include <iostream>
#define CSP_NAME "Longmai mToken GM3000 CSP V1.1"
using namespace std;
int main(int argc, char* argv[])
{
HCRYPTPROV hCryptProv = NULL;
cout << "Attempt to acquire context for CSP...";
if(!CryptAcquireContext(
&hCryptProv,
NULL,
CSP_NAME,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT
))
{
cout << endl << "Can't acquire context, Error code = 0x" << hex << GetLastError() << dec << endl;
return -1;
}
else
cout << "OK." << endl;
HCERTSTORE hCertStore = NULL;
cout << "Attempt to open the certificate storage...";
hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM, // The store provider type.
0, // The encoding type is not needed.
hCryptProv, // Use the epassNG HCRYPTPROV.
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY"
);
if(NULL == hCertStore)
{
cout << endl << "Can't open certificates store. Error code = 0x" << hex << GetLastError() << dec << endl;
}
else
cout << "OK." << endl;
// Enum the certficates. pCertContext must be NULL at the first time.
PCCERT_CONTEXT pCertContext = NULL;
DWORD dwTotalCert = 0;
while(pCertContext = CertEnumCertificatesInStore( hCertStore, pCertContext))
{
if(NULL == pCertContext)
break;
//////////////////////////////////////////////////////////////////////////
// How to get the subject name, see below:
// First we must get the length of the subject name.
DWORD dwNameLen = 0;
dwNameLen = CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0, NULL, NULL, 0
);
if(0 == dwNameLen)
{
cout << "Can't get the subject name of the certificate." << endl;
break;
}
// Now let's alloc memory for the subject name.
char* pszTemp = NULL;
pszTemp = new char[dwNameLen + 1]; // Plus 1 to hold the '\0'.
if(NULL == pszTemp)
break;
ZeroMemory(pszTemp, dwNameLen + 1);
// Second call to CertGetNameString() to get the subject name.
if(CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
NULL,
pszTemp,
dwNameLen + 1))
{
cout << "Oh, the subject name is : " << pszTemp << endl;
}
// Free the memory allocated for the subject name.
delete[] pszTemp;
pszTemp = NULL;
++dwTotalCert;
// Ok, we got the subject name.
//////////////////////////////////////////////////////////////////////////
}
if(0 == dwTotalCert)
{
cout << "No certficate find." << endl;
}
// Close the store.
if(CertCloseStore(hCertStore, 0))
{
cout << "Store closed. All information free." << endl;
}
else
{
cout << "Store closed. But some information in use." << endl;
}
getchar();
return 0;
}
PKCS#11接口
1.龙脉密码钥匙驱动实例工具等\mToken-GM3000\pkcs11\windows\samples\PKCStest\PKCStest.sln
DES
/*
[]=========================================================================[]
Copyright(C) Feitian Technologies Co., Ltd.
All rights reserved.
FILE:
BaseAll.cpp
DESC:
implementation of the DesTest class.
[]=========================================================================[]
*/
#include "DesTest.h"
#include "common.h"
DesTest::DesTest(char* dll_file_path):CBaseAll(dll_file_path)
{
m_hKey = 0;
}
DesTest::~DesTest()
{
}
void DesTest::Test()
{
if(CKR_OK != BaseAllStart())
return;
GenerateKey();
if(m_hKey == 0)
{
BaseAllEnd();
return ;
}
crypt_Single();
crypt_Update();
BaseAllEnd();
}
void DesTest::GenerateKey()
{
do{
SHOW_INFO("Generate Des key to test...");
CK_OBJECT_CLASS oClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_DES;
CK_BBOOL bTrue = true;
CK_BBOOL bFalse = false;
CK_ULONG ulLen = 8;
CK_MECHANISM mechanism = {CKM_DES_KEY_GEN, NULL_PTR, 0};
CK_ATTRIBUTE Destem[] = {
{CKA_CLASS, &oClass, sizeof(CK_OBJECT_CLASS)},
{CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE)},
{CKA_TOKEN, &bFalse, sizeof(CK_BBOOL)},
{CKA_PRIVATE, &bTrue, sizeof(CK_BBOOL)},
{CKA_ENCRYPT, &bTrue, sizeof(CK_BBOOL)},
{CKA_DECRYPT, &bTrue, sizeof(CK_BBOOL)},
{CKA_VALUE_LEN, &ulLen, sizeof(CK_ULONG)},
};
CK_ULONG ulCount = 7;
//generate key:
START_OP("generate DES key...")
CK_RV rv = m_gToken->C_GenerateKey(hSession, &mechanism, Destem, ulCount, &m_hKey);
CHECK_OP(rv)
}while(0);
}
void DesTest::crypt_Single()
{
const CK_ULONG DATA_LENGTH = 1024*3;
CK_BYTE bIn[DATA_LENGTH] = {0}, bTemp[DATA_LENGTH] = {0}, bOut[DATA_LENGTH] = {0};
CK_ULONG ulIn = 0, ulOut = 0, ulTemp = 0;
CK_ULONG Mechanism[3] = {CKM_DES_CBC, CKM_DES_ECB, CKM_DES_CBC_PAD};
CK_BYTE_PTR bHint[3] = {(CK_BYTE_PTR)"CKM_DES_CBC: ",\
(CK_BYTE_PTR)"CKM_DES_ECB: ",
(CK_BYTE_PTR)"CKM_DES_CBC_PAD: "};
SHOW_INFO("\nDES: C_Encrypt/C_Decrypt: \n");
for(int i=0;i<3;i++)
{
ulIn = 1000;
if(i==2)
ulIn = 1000;
for(register CK_ULONG i0 = 0;i0<ulIn;i0++)
bIn[i0] = (CK_BYTE)i0;
SHOW_INFO("\n* * * * * * * * * * * \n");
SHOW_INFO(bHint[i]);
//ecnrypt init:
CK_BYTE iv[8] = {'*','2','1','0','4','z','y','b'};
CK_MECHANISM ckMechanism = {Mechanism[i], iv, 8};
START_OP("Encrypting initialize.")
CK_RV rv = m_gToken->C_EncryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv)
START_OP("Encrypt the message.")
//Get the encrypted buffer's size:
//{{{Here, I do not invoke "C_Encrypt" twice for I had declared bTemp with a size=1024.
//If you do not declare the result's buffer previous,
//you should invoke twice to get the buffer's size, such as:[Decrypt is similar]
rv = m_gToken->C_Encrypt(hSession, bIn, ulIn, NULL, &ulTemp);
//}}}
CheckRV("C_Encrypt[get buffer's size]", rv);
//encrypt:
rv = m_gToken->C_Encrypt(hSession, bIn, ulIn, bTemp, &ulTemp);
CheckRV("C_Encrypt", rv);
CHECK_OP(rv);
SHOW_INFO("Data encrypted: \n");
ShowData(bTemp, ulTemp);
START_OP("Decrypting initialize.");
rv = m_gToken->C_DecryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv);
START_OP("Decrypt the message.");
//Get buffer's size:
rv = m_gToken->C_Decrypt(hSession, bTemp, ulTemp, NULL, &ulOut);
//Get decrypted data:
rv = m_gToken->C_Decrypt(hSession, bTemp, ulTemp, bOut, &ulOut);
CHECK_OP(rv);
SHOW_INFO("Data decrypted: \n");
ShowData(bOut, ulOut);
START_OP("Compare the original message and decrypted data: ");
if(0 == memcmp(bIn, bOut, ulOut))
{
CHECK_OP(CKR_OK);
}
else
{
SHOW_INFO("....[FAILED]\n");
}
}
}
void DesTest::crypt_Update()
{
const CK_ULONG DATA_LENGTH = 1024*3;
CK_BYTE bIn[DATA_LENGTH] = {0}, bTemp[DATA_LENGTH] = {0}, bOut[DATA_LENGTH] = {0};
CK_ULONG ulIn = 0, ulOut = 0, ulTemp = 0;
CK_ULONG Mechanism[3] = {CKM_DES_CBC, CKM_DES_ECB, CKM_DES_CBC_PAD};
CK_BYTE_PTR bHint[3] = {(CK_BYTE_PTR)"CKM_DES_CBC: ",\
(CK_BYTE_PTR)"CKM_DES_ECB: ",\
(CK_BYTE_PTR)"CKM_DES_CBC_PAD: "};
SHOW_INFO("\n* * * * * * * * * * * * * * * *\n");
for(int i=0;i<3;i++)
{
ulIn = 1000;
if(i == 2)
{//CKM_RC2_CBC_PAD
ulIn = 0xF1;
}
for(register CK_ULONG i0 = 0;i0<ulIn;i0++)
bIn[i0] = (CK_BYTE)i0;
SHOW_INFO("\n");
SHOW_INFO("\nDES: C_EncryptUpdate/C_DecryptUpdate: \n");
SHOW_INFO(bHint[i]);
//ecnrypt init:
CK_BYTE iv[8] = {'*','2','1','0','4','z','y','b'};
CK_MECHANISM ckMechanism = {Mechanism[i], iv, sizeof(iv)};
START_OP("Encrypting initialize.")
CK_RV rv = m_gToken->C_EncryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv)
CK_ULONG ulEncrypted = 0;
START_OP("Encrypt the message.");
//invoked twice:
const CK_ULONG ulEnc1stPice = 33;
rv = m_gToken->C_EncryptUpdate(hSession, bIn, ulEnc1stPice, NULL, &ulTemp);//get buffer's size.
rv = m_gToken->C_EncryptUpdate(hSession, bIn, ulEnc1stPice, bTemp, &ulTemp);
//}}}
CheckRV("C_Encrypt[get buffer's size]", rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
//encrypt:
//invoked twice:
rv = m_gToken->C_EncryptUpdate(hSession, &(bIn[ulEnc1stPice]), ulIn-ulEnc1stPice, NULL, &ulTemp);//get buffer's size.
rv = m_gToken->C_EncryptUpdate(hSession, &(bIn[ulEnc1stPice]), ulIn-ulEnc1stPice, &(bTemp[ulEncrypted]), &ulTemp);
CheckRV("C_Encrypt", rv);
CHECK_OP(rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
START_OP("C_EncryptFinal...");
rv = m_gToken->C_EncryptFinal(hSession, NULL, &ulTemp);
rv = m_gToken->C_EncryptFinal(hSession, &(bTemp[ulEncrypted]), &ulTemp);
CHECK_OP(rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
SHOW_INFO("Data encrypted: \n");
ShowData(bTemp, ulEncrypted);
START_OP("Decrypting initialize.");
rv = m_gToken->C_DecryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv);
START_OP("Decrypt the message.");
//Get buffer's size:
CK_ULONG ulDecrypt = 0;
const CK_ULONG ulDec1stPice = 11;
rv = m_gToken->C_DecryptUpdate(hSession, bTemp, ulDec1stPice, NULL, &ulOut);
rv = m_gToken->C_DecryptUpdate(hSession, bTemp, ulDec1stPice, bOut, &ulOut);
ulDecrypt +=ulOut;
ulOut = 0;
//Get decrypted data:
rv = m_gToken->C_DecryptUpdate(hSession, &(bTemp[ulDec1stPice]), ulEncrypted-ulDec1stPice, NULL, &ulOut);
rv = m_gToken->C_DecryptUpdate(hSession, &(bTemp[ulDec1stPice]), ulEncrypted-ulDec1stPice, &(bOut[ulDecrypt]), &ulOut);
CHECK_OP(rv);
ulDecrypt +=ulOut;
ulOut = 0;
START_OP("C_DecryptFinale...");
rv = m_gToken->C_DecryptFinal(hSession, NULL, &ulOut);
rv = m_gToken->C_DecryptFinal(hSession, &(bOut[ulDecrypt]), &ulOut);
CHECK_OP(rv);
ulDecrypt +=ulOut;
SHOW_INFO("Data decrypted: \n");
ShowData(bOut, ulDecrypt);
START_OP("Compare the original message and decrypted data: ");
if(0 == memcmp(bIn, bOut, ulDecrypt))
{
CHECK_OP(CKR_OK);
}
else
{
SHOW_INFO("....[FAILED]\n");
}
}
}
DES3
/*
[]=========================================================================[]
Copyright(C) Feitian Technologies Co., Ltd.
All rights reserved.
FILE:
BaseAll.cpp
DESC:
implementation of the Des3Test class.
[]=========================================================================[]
*/
#include "Des3Test.h"
#include "common.h"
Des3Test::Des3Test(char* dll_file_path):CBaseAll(dll_file_path)
{
m_hKey = 0;
}
Des3Test::~Des3Test()
{
}
void Des3Test::Test()
{
if(CKR_OK != BaseAllStart())
return;
GenerateKey();
if(m_hKey == 0)
{
BaseAllEnd();
return ;
}
crypt_Single();
crypt_Update();
BaseAllEnd();
}
void Des3Test::GenerateKey()
{
do{
SHOW_INFO("Generate Des3 key to test...");
CK_OBJECT_CLASS oClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_DES3;
CK_BBOOL bTrue = true;
CK_BBOOL bFalse = false;
CK_ULONG ulLen = 24;
CK_MECHANISM mechanism = {CKM_DES3_KEY_GEN, NULL_PTR, 0};
CK_ATTRIBUTE Des3tem[] = {
{CKA_CLASS, &oClass, sizeof(CK_OBJECT_CLASS)},
{CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE)},
{CKA_TOKEN, &bFalse, sizeof(CK_BBOOL)},
{CKA_PRIVATE, &bTrue, sizeof(CK_BBOOL)},
{CKA_ENCRYPT, &bTrue, sizeof(CK_BBOOL)},
{CKA_DECRYPT, &bTrue, sizeof(CK_BBOOL)},
{CKA_VALUE_LEN, &ulLen, sizeof(CK_ULONG)},
};
CK_ULONG ulCount = 7;
//generate key:
START_OP("generate DES3 key...")
CK_RV rv = m_gToken->C_GenerateKey(hSession, &mechanism, Des3tem, ulCount, &m_hKey);
CHECK_OP(rv)
}while(0);
}
void Des3Test::crypt_Single()
{
const CK_ULONG DATA_LENGTH = 1024;
CK_BYTE bIn[DATA_LENGTH] = {0}, bTemp[DATA_LENGTH] = {0}, bOut[DATA_LENGTH] = {0};
CK_ULONG ulIn = 0, ulOut = 0, ulTemp = 0;
CK_ULONG Mechanism[3] = {CKM_DES3_CBC, CKM_DES3_ECB, CKM_DES3_CBC_PAD};
CK_BYTE_PTR bHint[3] = {(CK_BYTE_PTR)"CKM_DES3_CBC: ",\
(CK_BYTE_PTR)"CKM_DES3_ECB: ",
(CK_BYTE_PTR)"CKM_DES3_CBC_PAD: "};
SHOW_INFO("\nDES: C_Encrypt/C_Decrypt: \n");
for(int i=0;i<3;i++)
{
ulIn = 256;
if(i==2)
ulIn = 337;
for(register CK_ULONG i0 = 0;i0<ulIn;i0++)
bIn[i0] = (CK_BYTE)i0;
SHOW_INFO("\n* * * * * * * * * * * \n");
SHOW_INFO(bHint[i]);
//ecnrypt init:
CK_BYTE iv[8] = {'*','2','1','0','4','z','y','b'};
CK_MECHANISM ckMechanism = {Mechanism[i], iv, 8};
START_OP("Encrypting initialize.")
CK_RV rv = m_gToken->C_EncryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv)
START_OP("Encrypt the message.")
//Get the encrypted buffer's size:
//{{{Here, I do not invoke "C_Encrypt" twice for I had declared bTemp with a size=1024.
//If you do not declare the result's buffer previous,
//you should invoke twice to get the buffer's size, such as:[Decrypt is similar]
rv = m_gToken->C_Encrypt(hSession, bIn, ulIn, NULL, &ulTemp);
//}}}
CheckRV("C_Encrypt[get buffer's size]", rv);
//encrypt:
rv = m_gToken->C_Encrypt(hSession, bIn, ulIn, bTemp, &ulTemp);
CheckRV("C_Encrypt", rv);
CHECK_OP(rv);
SHOW_INFO("Data encrypted: \n");
ShowData(bTemp, ulTemp);
START_OP("Decrypting initialize.");
rv = m_gToken->C_DecryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv);
START_OP("Decrypt the message.");
//Get buffer's size:
rv = m_gToken->C_Decrypt(hSession, bTemp, ulTemp, NULL, &ulOut);
//Get decrypted data:
rv = m_gToken->C_Decrypt(hSession, bTemp, ulTemp, bOut, &ulOut);
CHECK_OP(rv);
SHOW_INFO("Data decrypted: \n");
ShowData(bOut, ulOut);
START_OP("Compare the original message and decrypted data: ");
if(0 == memcmp(bIn, bOut, ulOut))
{
CHECK_OP(CKR_OK);
}
else
{
SHOW_INFO("....[FAILED]\n");
}
}
}
void Des3Test::crypt_Update()
{
const CK_ULONG DATA_LENGTH = 1024;
CK_BYTE bIn[DATA_LENGTH] = {0}, bTemp[DATA_LENGTH] = {0}, bOut[DATA_LENGTH] = {0};
CK_ULONG ulIn = 0, ulOut = 0, ulTemp = 0;
CK_ULONG Mechanism[3] = {CKM_DES3_CBC, CKM_DES3_ECB, CKM_DES3_CBC_PAD};
CK_BYTE_PTR bHint[3] = {(CK_BYTE_PTR)"CKM_DES3_CBC: ",\
(CK_BYTE_PTR)"CKM_DES3_ECB: ",\
(CK_BYTE_PTR)"CKM_DES3_CBC_PAD: "};
SHOW_INFO("\n* * * * * * * * * * * * * * * *\n");
for(int i=0;i<3;i++)
{
ulIn = 256;
if(i == 2)
{//CKM_RC2_CBC_PAD
ulIn = 253;
}
for(register CK_ULONG i0 = 0;i0<ulIn;i0++)
bIn[i0] = (CK_BYTE)i0;
SHOW_INFO("\n");
SHOW_INFO("\nDES: C_EncryptUpdate/C_DecryptUpdate: \n");
SHOW_INFO(bHint[i]);
//ecnrypt init:
CK_BYTE iv[8] = {'*','2','1','0','4','z','y','b'};
CK_MECHANISM ckMechanism = {Mechanism[i], iv, sizeof(iv)};
START_OP("Encrypting initialize.")
CK_RV rv = m_gToken->C_EncryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv)
CK_ULONG ulEncrypted = 0;
START_OP("Encrypt the message.");
//invoked twice:
const CK_ULONG ulEnc1stPice = 33;
rv = m_gToken->C_EncryptUpdate(hSession, bIn, ulEnc1stPice, NULL, &ulTemp);//get buffer's size.
rv = m_gToken->C_EncryptUpdate(hSession, bIn, ulEnc1stPice, bTemp, &ulTemp);
//}}}
CheckRV("C_Encrypt[get buffer's size]", rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
//encrypt:
//invoked twice:
rv = m_gToken->C_EncryptUpdate(hSession, &(bIn[ulEnc1stPice]), ulIn-ulEnc1stPice, NULL, &ulTemp);//get buffer's size.
rv = m_gToken->C_EncryptUpdate(hSession, &(bIn[ulEnc1stPice]), ulIn-ulEnc1stPice, &(bTemp[ulEncrypted]), &ulTemp);
CheckRV("C_Encrypt", rv);
CHECK_OP(rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
START_OP("C_EncryptFinal...");
rv = m_gToken->C_EncryptFinal(hSession, NULL, &ulTemp);
rv = m_gToken->C_EncryptFinal(hSession, &(bTemp[ulEncrypted]), &ulTemp);
CHECK_OP(rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
SHOW_INFO("Data encrypted: \n");
ShowData(bTemp, ulEncrypted);
START_OP("Decrypting initialize.");
rv = m_gToken->C_DecryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv);
START_OP("Decrypt the message.");
//Get buffer's size:
CK_ULONG ulDecrypt = 0;
const CK_ULONG ulDec1stPice = 11;
rv = m_gToken->C_DecryptUpdate(hSession, bTemp, ulDec1stPice, NULL, &ulOut);
rv = m_gToken->C_DecryptUpdate(hSession, bTemp, ulDec1stPice, bOut, &ulOut);
ulDecrypt +=ulOut;
ulOut = 0;
//Get decrypted data:
rv = m_gToken->C_DecryptUpdate(hSession, &(bTemp[ulDec1stPice]), ulEncrypted-ulDec1stPice, NULL, &ulOut);
rv = m_gToken->C_DecryptUpdate(hSession, &(bTemp[ulDec1stPice]), ulEncrypted-ulDec1stPice, &(bOut[ulDecrypt]), &ulOut);
CHECK_OP(rv);
ulDecrypt +=ulOut;
ulOut = 0;
START_OP("C_DecryptFinale...");
rv = m_gToken->C_DecryptFinal(hSession, NULL, &ulOut);
rv = m_gToken->C_DecryptFinal(hSession, &(bOut[ulDecrypt]), &ulOut);
CHECK_OP(rv);
ulDecrypt +=ulOut;
SHOW_INFO("Data decrypted: \n");
ShowData(bOut, ulDecrypt);
START_OP("Compare the original message and decrypted data: ");
if(0 == memcmp(bIn, bOut, ulDecrypt))
{
CHECK_OP(CKR_OK);
}
else
{
SHOW_INFO("....[FAILED]\n");
}
}
}
RC2
/*
[]=========================================================================[]
Copyright(C) Feitian Technologies Co., Ltd.
All rights reserved.
FILE:
rc2test.cpp
DESC:
implementation of the RC2Test class.
[]=========================================================================[]
*/
#include "RC2Test.h"
#include "common.h"
RC2Test::RC2Test(char* dll_file_path):CBaseAll(dll_file_path)
{
m_hKey = 0;
}
RC2Test::~RC2Test()
{
}
void RC2Test::GenerateKey()
{
do{
SHOW_INFO("Generate RC2 key to test...");
CK_OBJECT_CLASS oClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_RC2;
CK_BBOOL bTrue = true;
CK_BBOOL bFalse = false;
CK_ULONG ulLen = 16;//bytes:1~128
CK_MECHANISM mechanism = {CKM_RC2_KEY_GEN, NULL_PTR, 0};
CK_ATTRIBUTE rc2tem[] = {
{CKA_CLASS, &oClass, sizeof(CK_OBJECT_CLASS)},
{CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE)},
{CKA_TOKEN, &bFalse, sizeof(CK_BBOOL)},
{CKA_PRIVATE, &bTrue, sizeof(CK_BBOOL)},
{CKA_ENCRYPT, &bTrue, sizeof(CK_BBOOL)},
{CKA_DECRYPT, &bTrue, sizeof(CK_BBOOL)},
{CKA_VALUE_LEN, &ulLen, sizeof(CK_ULONG)},
};
CK_ULONG ulCount = 7;
//generate key:
START_OP("generate RC2 key...")
CK_RV rv = m_gToken->C_GenerateKey(hSession, &mechanism, rc2tem, ulCount, &m_hKey);
CHECK_OP(rv)
}while(0);
}
void RC2Test::Test()
{
if(CKR_OK != BaseAllStart())
return;
GenerateKey();
if(m_hKey == 0)
{
BaseAllEnd();
return ;
}
crypt_Single();
crypt_Update();
BaseAllEnd();
}
void RC2Test::crypt_Single()
{
const CK_ULONG DATA_LENGTH = 1024;
CK_BYTE bIn[DATA_LENGTH] = {0}, bTemp[DATA_LENGTH] = {0}, bOut[DATA_LENGTH] = {0};
CK_ULONG ulIn = 0, ulOut = 0, ulTemp = 0;
CK_ULONG Mechanism[3] = {CKM_RC2_CBC, CKM_RC2_ECB, CKM_RC2_CBC_PAD};
CK_BYTE_PTR bHint[3] = {(CK_BYTE_PTR)"CKM_RC2_CBC: ",\
(CK_BYTE_PTR)"CKM_RC2_ECB: ",
(CK_BYTE_PTR)"CKM_RC2_CBC_PAD: "};
SHOW_INFO("\nRC2: C_Encrypt/C_Decrypt: \n");
for(int i=0;i<3;i++)
{
ulIn = 256;
if(i==2)
ulIn = 337;
for(register CK_ULONG i0 = 0;i0<ulIn;i0++)
bIn[i0] = (CK_BYTE)i0;
SHOW_INFO("\n* * * * * * * * * * * \n");
SHOW_INFO(bHint[i]);
//ecnrypt init:
CK_BYTE iv[8] = {'*','2','1','0','4','z','y','b'};
CK_RC2_CBC_PARAMS Param;
memcpy(Param.iv, iv, sizeof(iv));
Param.ulEffectiveBits = 16*8;
CK_MECHANISM ckMechanism = {Mechanism[i], &Param, sizeof(CK_RC2_CBC_PARAMS)};
START_OP("Encrypting initialize.")
CK_RV rv = m_gToken->C_EncryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv)
START_OP("Encrypt the message.")
//Get the encrypted buffer's size:
//{{{Here, I do not invoke "C_Encrypt" twice for I had declared bTemp with a size=1024.
//If you do not declare the result's buffer previous,
//you should invoke twice to get the buffer's size, such as:[Decrypt is similar]
rv = m_gToken->C_Encrypt(hSession, bIn, ulIn, NULL, &ulTemp);
//}}}
CheckRV("C_Encrypt[get buffer's size]", rv);
//encrypt:
rv = m_gToken->C_Encrypt(hSession, bIn, ulIn, bTemp, &ulTemp);
CheckRV("C_Encrypt", rv);
CHECK_OP(rv);
SHOW_INFO("Data encrypted: \n");
ShowData(bTemp, ulTemp);
START_OP("Decrypting initialize.");
rv = m_gToken->C_DecryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv);
START_OP("Decrypt the message.");
//Get buffer's size:
rv = m_gToken->C_Decrypt(hSession, bTemp, ulTemp, NULL, &ulOut);
//Get decrypted data:
rv = m_gToken->C_Decrypt(hSession, bTemp, ulTemp, bOut, &ulOut);
CHECK_OP(rv);
SHOW_INFO("Data decrypted: \n");
ShowData(bOut, ulOut);
START_OP("Compare the original message and decrypted data: ");
if(0 == memcmp(bIn, bOut, ulOut))
{
CHECK_OP(CKR_OK);
}
else
{
SHOW_INFO("....[FAILED]\n");
}
}
}
void RC2Test::crypt_Update()
{
const CK_ULONG DATA_LENGTH = 1024;
CK_BYTE bIn[DATA_LENGTH] = {0}, bTemp[DATA_LENGTH] = {0}, bOut[DATA_LENGTH] = {0};
CK_ULONG ulIn = 0, ulOut = 0, ulTemp = 0;
CK_ULONG Mechanism[3] = {CKM_RC2_CBC, CKM_RC2_ECB, CKM_RC2_CBC_PAD};
CK_BYTE_PTR bHint[3] = {(CK_BYTE_PTR)"CKM_RC2_CBC: ",\
(CK_BYTE_PTR)"CKM_RC2_ECB: ",\
(CK_BYTE_PTR)"CKM_RC2_CBC_PAD: "};
SHOW_INFO("\n* * * * * * * * * * * * * * * *\n");
for(int i=0;i<3;i++)
{
ulIn = 256;
if(i == 2)
{//CKM_RC2_CBC_PAD
ulIn = 253;
}
for(register CK_ULONG i0 = 0;i0<ulIn;i0++)
bIn[i0] = (CK_BYTE)i0;
SHOW_INFO("\n");
SHOW_INFO("\nRC2: C_EncryptUpdate/C_DecryptUpdate: \n");
SHOW_INFO(bHint[i]);
//ecnrypt init:
CK_BYTE iv[8] = {'*','2','1','0','4','z','y','b'};
CK_RC2_CBC_PARAMS Param;
memcpy(Param.iv, iv, sizeof(iv));
Param.ulEffectiveBits = 16*8;
CK_MECHANISM ckMechanism = {Mechanism[i], &Param, sizeof(CK_RC2_CBC_PARAMS)};
START_OP("Encrypting initialize.")
CK_RV rv = m_gToken->C_EncryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv)
CK_ULONG ulEncrypted = 0;
START_OP("Encrypt the message.");
//invoked twice:
const CK_ULONG ulEnc1stPice = 33;
rv = m_gToken->C_EncryptUpdate(hSession, bIn, ulEnc1stPice, NULL, &ulTemp);//get buffer's size.
rv = m_gToken->C_EncryptUpdate(hSession, bIn, ulEnc1stPice, bTemp, &ulTemp);
//}}}
CheckRV("C_Encrypt[get buffer's size]", rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
//encrypt:
//invoked twice:
rv = m_gToken->C_EncryptUpdate(hSession, &(bIn[ulEnc1stPice]), ulIn-ulEnc1stPice, NULL, &ulTemp);//get buffer's size.
rv = m_gToken->C_EncryptUpdate(hSession, &(bIn[ulEnc1stPice]), ulIn-ulEnc1stPice, &(bTemp[ulEncrypted]), &ulTemp);
CheckRV("C_Encrypt", rv);
CHECK_OP(rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
START_OP("C_EncryptFinal...");
rv = m_gToken->C_EncryptFinal(hSession, NULL, &ulTemp);
rv = m_gToken->C_EncryptFinal(hSession, &(bTemp[ulEncrypted]), &ulTemp);
CHECK_OP(rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
SHOW_INFO("Data encrypted: \n");
ShowData(bTemp, ulEncrypted);
START_OP("Decrypting initialize.");
rv = m_gToken->C_DecryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv);
START_OP("Decrypt the message.");
//Get buffer's size:
CK_ULONG ulDecrypt = 0;
const CK_ULONG ulDec1stPice = 11;
rv = m_gToken->C_DecryptUpdate(hSession, bTemp, ulDec1stPice, NULL, &ulOut);
rv = m_gToken->C_DecryptUpdate(hSession, bTemp, ulDec1stPice, bOut, &ulOut);
ulDecrypt +=ulOut;
ulOut = 0;
//Get decrypted data:
rv = m_gToken->C_DecryptUpdate(hSession, &(bTemp[ulDec1stPice]), ulEncrypted-ulDec1stPice, NULL, &ulOut);
rv = m_gToken->C_DecryptUpdate(hSession, &(bTemp[ulDec1stPice]), ulEncrypted-ulDec1stPice, &(bOut[ulDecrypt]), &ulOut);
CHECK_OP(rv);
ulDecrypt +=ulOut;
ulOut = 0;
START_OP("C_DecryptFinale...");
rv = m_gToken->C_DecryptFinal(hSession, NULL, &ulOut);
rv = m_gToken->C_DecryptFinal(hSession, &(bOut[ulDecrypt]), &ulOut);
CHECK_OP(rv);
ulDecrypt +=ulOut;
SHOW_INFO("Data decrypted: \n");
ShowData(bOut, ulDecrypt);
START_OP("Compare the original message and decrypted data: ");
if(0 == memcmp(bIn, bOut, ulDecrypt))
{
CHECK_OP(CKR_OK);
}
else
{
SHOW_INFO("....[FAILED]\n");
}
}
}
RC4
/*
[]=========================================================================[]
Copyright(C) Feitian Technologies Co., Ltd.
All rights reserved.
FILE:
rc4test.cpp
DESC:
implementation of the RC4Test class.
[]=========================================================================[]
*/
#include "RC4Test.h"
#include "common.h"
RC4Test::RC4Test(char* dll_file_path):CBaseAll(dll_file_path)
{
m_hKey = 0;
}
RC4Test::~RC4Test()
{
m_hKey = 0;
}
void RC4Test::Test()
{
if(CKR_OK != BaseAllStart())
return;
GenerateKey();
if(m_hKey == 0)
return ;
crypt_single();
crypt_Update();
BaseAllEnd();
}
void RC4Test::GenerateKey()
{
do{
CK_OBJECT_CLASS oClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_RC4;
CK_BBOOL bTrue = true;
CK_BBOOL bFalse = false;
CK_ULONG ulLen = 16;
CK_ATTRIBUTE rc4tem[] = {
{CKA_CLASS, &oClass, sizeof(CK_OBJECT_CLASS)},
{CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE)},
{CKA_TOKEN, &bFalse, sizeof(CK_BBOOL)},
{CKA_PRIVATE, &bTrue, sizeof(CK_BBOOL)},
{CKA_ENCRYPT, &bTrue, sizeof(CK_BBOOL)},
{CKA_DECRYPT, &bTrue, sizeof(CK_BBOOL)},
{CKA_VALUE_LEN, &ulLen, sizeof(CK_ULONG)},
};
CK_ULONG ulCount = 7;
CK_MECHANISM mechanism = {CKM_RC4_KEY_GEN, NULL, 0};
//generate key:
START_OP("generate RC4 key...");
CK_RV rv = m_gToken->C_GenerateKey(hSession, &mechanism, rc4tem, ulCount, &m_hKey);
CHECK_OP(rv);
}while(0);
}
void RC4Test::crypt_single()
{
const CK_ULONG DATA_LENGTH = 1024;
CK_BYTE bIn[DATA_LENGTH] = {0}, bTemp[DATA_LENGTH] = {0}, bOut[DATA_LENGTH] = {0};
CK_ULONG ulIn = 0, ulOut = 0, ulTemp = 0;
CK_ULONG Mechanism = {CKM_RC4};
CK_BYTE_PTR bHint = {(CK_BYTE_PTR)"CKM_RC4: "};
SHOW_INFO("\nRC4: C_Encrypt/C_Decrypt: \n");
do{
ulIn = 256;
for(register CK_ULONG i0 = 0;i0<ulIn;i0++)
bIn[i0] = (CK_BYTE)i0;
SHOW_INFO("\n* * * * * * * * * * * \n");
SHOW_INFO(bHint);
//ecnrypt init:
CK_MECHANISM ckMechanism = {Mechanism, NULL, 0};
START_OP("Encrypting initialize.");
CK_RV rv = m_gToken->C_EncryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv);
START_OP("Encrypt the message.");
//Get seze:
ulTemp = 0;
rv = m_gToken->C_Encrypt(hSession, bIn, ulIn, NULL, &ulTemp);
//encrypt:
rv = m_gToken->C_Encrypt(hSession, bIn, ulIn, bTemp, &ulTemp);
CheckRV("C_Encrypt", rv);
CHECK_OP(rv);
SHOW_INFO("Data encrypted: \n");
ShowData(bTemp, ulTemp);
START_OP("Decrypting initialize.");
rv = m_gToken->C_DecryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv);
START_OP("Decrypt the message.");
//Get size:
ulOut = 0;
rv = m_gToken->C_Decrypt(hSession, bTemp, ulTemp, NULL, &ulOut);
//Get decrypted data:
rv = m_gToken->C_Decrypt(hSession, bTemp, ulTemp, bOut, &ulOut);
CHECK_OP(rv);
SHOW_INFO("Data decrypted: \n");
ShowData(bOut, ulOut);
START_OP("Compare the original message and decrypted data: ");
if(0 == memcmp(bIn, bOut, ulOut))
{
CHECK_OP(CKR_OK);
}
else
{
SHOW_INFO("....[FAILED]\n");
}
}while(0);
}
void RC4Test::crypt_Update()
{
const CK_ULONG DATA_LENGTH = 1024;
CK_BYTE bIn[DATA_LENGTH] = {0}, bTemp[DATA_LENGTH] = {0}, bOut[DATA_LENGTH] = {0};
CK_ULONG ulIn = 0, ulOut = 0, ulTemp = 0;
CK_BYTE_PTR bHint = {(CK_BYTE_PTR)"CKM_RC4 "};
SHOW_INFO("\n* * * * * * * * * * * * * * * *\n");
do{
ulIn = 257;
for(register CK_ULONG i0 = 0;i0<ulIn;i0++)
bIn[i0] = (CK_BYTE)i0;
SHOW_INFO("\n");
SHOW_INFO("\nRC4: C_EncryptUpdate/C_DecryptUpdate: \n");
SHOW_INFO(bHint);
//ecnrypt init:
CK_MECHANISM ckMechanism = {CKM_RC4, NULL, 0};
START_OP("Encrypting initialize.")
CK_RV rv = m_gToken->C_EncryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv)
CK_ULONG ulEncrypted = 0;
START_OP("Encrypt the message.");
//invoked twice:
const CK_ULONG ulEnc1stPice = 33;
//Get size:
rv = m_gToken->C_EncryptUpdate(hSession, bIn, ulEnc1stPice, NULL, &ulTemp);
CheckRV("C_Encrypt[get buffer's size]", rv);
//alloc memory(omit...)
//Get encrypted result:
rv = m_gToken->C_EncryptUpdate(hSession, bIn, ulEnc1stPice, bTemp, &ulTemp);
//}}}
ulEncrypted+=ulTemp;
ulTemp = 0;
//encrypt:
//invoked twice:
rv = m_gToken->C_EncryptUpdate(hSession, bIn, ulIn-ulEnc1stPice, NULL, &ulTemp);
rv = m_gToken->C_EncryptUpdate(hSession, &(bIn[ulEnc1stPice]), ulIn-ulEnc1stPice, &(bTemp[ulEncrypted]), &ulTemp);
CheckRV("C_Encrypt", rv);
CHECK_OP(rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
START_OP("C_EncryptFinal...");
rv = m_gToken->C_EncryptFinal(hSession, NULL, &ulTemp);
rv = m_gToken->C_EncryptFinal(hSession, &(bTemp[ulEncrypted]), &ulTemp);
CHECK_OP(rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
SHOW_INFO("Data encrypted: \n");
ShowData(bTemp, ulEncrypted);
START_OP("Decrypting initialize.");
rv = m_gToken->C_DecryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv);
START_OP("Decrypt the message.");
//Get buffer's size:
CK_ULONG ulDecrypt = 0;
const CK_ULONG ulDec1stPice = 11;
rv = m_gToken->C_DecryptUpdate(hSession, bTemp, ulDec1stPice, NULL, &ulOut);
//alloc memory(omit...)
rv = m_gToken->C_DecryptUpdate(hSession, bTemp, ulDec1stPice, bOut, &ulOut);
ulDecrypt +=ulOut;
ulOut = 0;
rv = m_gToken->C_DecryptUpdate(hSession, bTemp, ulEncrypted-ulDec1stPice, NULL, &ulOut);
//Get decrypted data:
rv = m_gToken->C_DecryptUpdate(hSession, &(bTemp[ulDec1stPice]), ulEncrypted-ulDec1stPice, &(bOut[ulDecrypt]), &ulOut);
CHECK_OP(rv);
ulDecrypt +=ulOut;
ulOut = 0;
START_OP("C_DecryptFinale...");
rv = m_gToken->C_DecryptFinal(hSession, NULL, &ulOut);
rv = m_gToken->C_DecryptFinal(hSession, &(bOut[ulDecrypt]), &ulOut);
CHECK_OP(rv);
ulDecrypt +=ulOut;
SHOW_INFO("Data decrypted: \n");
ShowData(bOut, ulDecrypt);
START_OP("Compare the original message and decrypted data: ");
if(0 == memcmp(bIn, bOut, ulDecrypt))
{
CHECK_OP(CKR_OK);
}
else
{
SHOW_INFO("....[FAILED]\n");
}
}while(0);
}
RSA
/*
[]=========================================================================[]
Copyright(C) Feitian Technologies Co., Ltd.
All rights reserved.
FILE:
rsatest.cpp
DESC:
implementation of the RSATest class.
[]=========================================================================[]
*/
#include "RSATest.h"
#include "common.h"
RSATest::RSATest(char* dll_file_path):CBaseAll(dll_file_path)
{
}
RSATest::~RSATest()
{
}
void RSATest::RsaKeyGenerationTest(void)
{
if(CKR_OK != BaseAllStart())
return;
SHOW_INFO("\n\nThe next demo will generate a RSA key pair on UsbToken.")
CK_RV rv = CKR_OK;
CK_BBOOL bTrue = TRUE;
CK_ULONG ulModulusBits = MODULUS_BIT_LENGTH;
CK_BYTE subject[] = "Sample RSA Key Pair";
CK_ULONG keyType = CKK_RSA;
CK_OBJECT_HANDLE hPubKey = 0;
CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
CK_ATTRIBUTE pubTemplate[] =
{
{CKA_CLASS, &pubClass, sizeof(pubClass)},
{CKA_KEY_TYPE, &keyType, sizeof(keyType)},
{CKA_SUBJECT, subject, sizeof(subject)},
{CKA_MODULUS_BITS, &ulModulusBits, sizeof(ulModulusBits)},
{CKA_ENCRYPT, &bTrue, sizeof(bTrue)},
{CKA_TOKEN, &bTrue, sizeof(bTrue)},
{CKA_WRAP, &bTrue, sizeof(bTrue)},
};
CK_OBJECT_HANDLE hPriKey = 0;
CK_OBJECT_CLASS priClass = CKO_PRIVATE_KEY;
CK_ATTRIBUTE priTemplate[] = {
{CKA_CLASS, &priClass, sizeof(priClass)},
{CKA_KEY_TYPE, &keyType, sizeof(keyType)},
{CKA_SUBJECT, subject, sizeof(subject)},
{CKA_DECRYPT, &bTrue, sizeof(bTrue)},
{CKA_PRIVATE, &bTrue, sizeof(bTrue)},
{CKA_SENSITIVE, &bTrue, sizeof(bTrue)},
{CKA_TOKEN, &bTrue, sizeof(bTrue)},
{CKA_EXTRACTABLE, &bTrue, sizeof(bTrue)},
{CKA_UNWRAP, &bTrue, sizeof(bTrue)},
};
CK_MECHANISM keyGenMechanism = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
CK_MECHANISM ckMechanism = {CKM_RSA_PKCS, NULL_PTR, 0};
CK_BYTE pbMsg[] = "UsbToken RunRsaKeyGenerationTest...";
CK_ULONG ulMsgLen = strlen((const char *)pbMsg);
CK_BYTE bSignatureBuffer[MODULUS_BIT_LENGTH] = {0};
CK_ULONG ulSignatureLen = 0;
CK_BYTE_PTR pbCipherBuffer = NULL;
CK_ULONG ulCipherLen = 0;
CK_BYTE_PTR pbRestoredMsg = NULL;
CK_ULONG ulRestoredMsgLen = 0;
do {
START_OP("Generating public/private key pair...");
rv = m_gToken->C_GenerateKeyPair(hSession, &keyGenMechanism,
pubTemplate, countof(pubTemplate),
priTemplate, countof(priTemplate),
&hPubKey, &hPriKey);
CHECK_OP(rv)
// Try Sign and Verify operations with the key pair.
// Sign a message.
SHOW_INFO("\nThe message to be signed is \"")
ShowData(pbMsg, ulMsgLen);
ulSignatureLen = sizeof(bSignatureBuffer);
START_OP("Signing initialize.");
rv = m_gToken->C_SignInit(hSession, &ckMechanism, hPriKey);
CHECK_OP(rv);
START_OP("Sign the message.")
rv = m_gToken->C_Sign(hSession,
pbMsg,
ulMsgLen,
bSignatureBuffer, &ulSignatureLen);
CHECK_OP(rv)
SHOW_INFO("\nSignature is:\n");
ShowData(bSignatureBuffer, ulSignatureLen);
// Verify the previously signed message.
START_OP("Verifying initialize.")
rv = m_gToken->C_VerifyInit(hSession, &ckMechanism, hPubKey);
CHECK_OP(rv)
START_OP("Verify the message.")
rv = m_gToken->C_Verify(hSession,
pbMsg, ulMsgLen,
bSignatureBuffer, ulSignatureLen);
CHECK_OP(rv)
// Encrypt a message.
SHOW_INFO("\nThe message to be Encrypt is: ")
ShowData(pbMsg, ulMsgLen);
START_OP("Encrypting initialize.")
rv = m_gToken->C_EncryptInit(hSession,
&ckMechanism,
hPubKey);
CHECK_OP(rv)
START_OP("Obtain the size of the encrypted message....")
rv = m_gToken->C_Encrypt(hSession, pbMsg, ulMsgLen, NULL_PTR, &ulCipherLen);
CHECK_OP(rv)
START_OP("Allocate buffer for the encrypted message.")
pbCipherBuffer = (CK_BYTE_PTR)malloc(ulCipherLen);
if (! pbCipherBuffer)
CHECK_OP(CKR_HOST_MEMORY)
else
CHECK_OP(CKR_OK);
START_OP("Encrypt the message....");
memset(pbCipherBuffer, 0, ulCipherLen);
rv = m_gToken->C_Encrypt(hSession, pbMsg, ulMsgLen,
pbCipherBuffer, &ulCipherLen);
CHECK_OP(rv);
SHOW_INFO("Data encrypted: ");
ShowData(pbCipherBuffer, ulCipherLen);
START_OP("Decrypting initialize....")
rv = m_gToken->C_DecryptInit(hSession,
&ckMechanism,
hPriKey);
CHECK_OP(rv)
START_OP("Obtain the size of the decrypted message....")
rv = m_gToken->C_Decrypt(hSession, pbCipherBuffer,
ulCipherLen, NULL_PTR, &ulRestoredMsgLen);
CHECK_OP(rv)
START_OP("Allocate buffer for the decrypted message.")
pbRestoredMsg = (CK_BYTE_PTR)malloc(ulRestoredMsgLen + 1);
if (! pbRestoredMsg)
CHECK_OP(CKR_HOST_MEMORY)
else
CHECK_OP(CKR_OK);
memset(pbRestoredMsg, 0, ulRestoredMsgLen + 1);
START_OP("Decrypt the message.")
rv = m_gToken->C_Decrypt(hSession, pbCipherBuffer, ulCipherLen,
pbRestoredMsg, &ulRestoredMsgLen);
CHECK_OP(rv)
// Decrypt a message.
SHOW_INFO("\nThe message decrypted is \n")
ShowData(pbRestoredMsg, ulRestoredMsgLen);
START_OP("Verify the message.");
if(0 == memcmp(pbMsg, pbRestoredMsg, ulRestoredMsgLen))
CHECK_OP(CKR_OK)
else
SHOW_INFO("....[FAILED]\n")
// Remove the RSA key pair from the UsbToken.
START_OP("Proceed to remove the RSA key pair from the token.");
rv = m_gToken->C_DestroyObject(hSession, hPubKey);
CHECK_OP(rv);
START_OP("Remove private key obeject.");
rv = m_gToken->C_DestroyObject(hSession, hPriKey);
CHECK_OP(rv);
START_OP("Logout normally...")
rv = m_gToken->C_Logout(hSession);
CHECK_OP(rv);
}while (0);
// Release the memory.
if(pbCipherBuffer)
{
free(pbCipherBuffer);
pbCipherBuffer = NULL;
}
if(pbRestoredMsg)
{
free(pbRestoredMsg);
pbCipherBuffer = NULL;
}
BaseAllEnd();
}
AES
/*
[]=========================================================================[]
Copyright(C) Feitian Technologies Co., Ltd.
All rights reserved.
FILE:
BaseAll.cpp
DESC:
implementation of the DesTest class.
[]=========================================================================[]
*/
#include "AESTest.h"
#include "common.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
AESTest::AESTest(char* dll_file_path):CBaseAll(dll_file_path)
{
m_hKey = 0;
}
AESTest::~AESTest()
{
}
void AESTest::Test()
{
if(CKR_OK != BaseAllStart())
return;
GenerateKey();
if(m_hKey == 0)
{
BaseAllEnd();
return ;
}
crypt_Single();
crypt_Update();
BaseAllEnd();
}
void AESTest::GenerateKey()
{
do{
SHOW_INFO("Generate Des key to test...");
CK_OBJECT_CLASS oClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_AES;
CK_BBOOL bTrue = true;
CK_BBOOL bFalse = false;
CK_ULONG ulLen = 16;
CK_MECHANISM mechanism = {CKM_AES_KEY_GEN, NULL_PTR, 0};
CK_ATTRIBUTE Destem[] = {
{CKA_CLASS, &oClass, sizeof(CK_OBJECT_CLASS)},
{CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE)},
{CKA_TOKEN, &bFalse, sizeof(CK_BBOOL)},
{CKA_PRIVATE, &bTrue, sizeof(CK_BBOOL)},
{CKA_ENCRYPT, &bTrue, sizeof(CK_BBOOL)},
{CKA_DECRYPT, &bTrue, sizeof(CK_BBOOL)},
{CKA_VALUE_LEN, &ulLen, sizeof(CK_ULONG)},
};
CK_ULONG ulCount = 7;
//generate key:
START_OP("generate AES key...")
CK_RV rv = m_gToken->C_GenerateKey(hSession, &mechanism, Destem, ulCount, &m_hKey);
CHECK_OP(rv)
}while(0);
}
void AESTest::crypt_Single()
{
const CK_ULONG DATA_LENGTH = 1024*3;
CK_BYTE bIn[DATA_LENGTH] = {0}, bTemp[DATA_LENGTH] = {0}, bOut[DATA_LENGTH] = {0};
CK_ULONG ulIn = 0, ulOut = 0, ulTemp = 0;
CK_ULONG Mechanism[3] = {CKM_AES_CBC, CKM_AES_ECB, CKM_AES_CBC_PAD};
CK_BYTE_PTR bHint[3] = {(CK_BYTE_PTR)"CKM_AES_CBC: ",\
(CK_BYTE_PTR)"CKM_AES_ECB: ",
(CK_BYTE_PTR)"CKM_AES_CBC_PAD: "};
SHOW_INFO("\nAES: C_Encrypt/C_Decrypt: \n");
for(int i=0;i<3;i++)
{
ulIn = 1024;
if(i==2)//pad
ulIn = 1000;
for(register CK_ULONG i0 = 0;i0<ulIn;i0++)
bIn[i0] = (CK_BYTE)i0;
SHOW_INFO("\n* * * * * * * * * * * \n");
SHOW_INFO(bHint[i]);
//ecnrypt init:
CK_BYTE iv[16] = {'*','2','1','0','4','z','y','b','*','2','1','0','4','z','y','b'};
CK_MECHANISM ckMechanism = {Mechanism[i], iv, 16};
START_OP("Encrypting initialize.")
CK_RV rv = m_gToken->C_EncryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv)
START_OP("Encrypt the message.")
//Get the encrypted buffer's size:
//{{{Here, I do not invoke "C_Encrypt" twice for I had declared bTemp with a size=1024.
//If you do not declare the result's buffer previous,
//you should invoke twice to get the buffer's size, such as:[Decrypt is similar]
rv = m_gToken->C_Encrypt(hSession, bIn, ulIn, NULL, &ulTemp);
//}}}
CheckRV("C_Encrypt[get buffer's size]", rv);
//encrypt:
rv = m_gToken->C_Encrypt(hSession, bIn, ulIn, bTemp, &ulTemp);
CheckRV("C_Encrypt", rv);
CHECK_OP(rv);
SHOW_INFO("Data encrypted: \n");
ShowData(bTemp, ulTemp);
START_OP("Decrypting initialize.");
rv = m_gToken->C_DecryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv);
START_OP("Decrypt the message.");
//Get buffer's size:
rv = m_gToken->C_Decrypt(hSession, bTemp, ulTemp, NULL, &ulOut);
//Get decrypted data:
rv = m_gToken->C_Decrypt(hSession, bTemp, ulTemp, bOut, &ulOut);
CHECK_OP(rv);
SHOW_INFO("Data decrypted: \n");
ShowData(bOut, ulOut);
START_OP("Compare the original message and decrypted data: ");
if(0 == memcmp(bIn, bOut, ulOut))
{
CHECK_OP(CKR_OK);
}
else
{
SHOW_INFO("....[FAILED]\n");
}
}
}
void AESTest::crypt_Update()
{
const CK_ULONG DATA_LENGTH = 1024*3;
CK_BYTE bIn[DATA_LENGTH] = {0}, bTemp[DATA_LENGTH] = {0}, bOut[DATA_LENGTH] = {0};
CK_ULONG ulIn = 0, ulOut = 0, ulTemp = 0;
CK_ULONG Mechanism[3] = {CKM_AES_CBC, CKM_AES_ECB, CKM_AES_CBC_PAD};
CK_BYTE_PTR bHint[3] = {(CK_BYTE_PTR)"CKM_AES_CBC: ",\
(CK_BYTE_PTR)"CKM_AES_ECB: ",\
(CK_BYTE_PTR)"CKM_AES_CBC_PAD: "};
SHOW_INFO("\n* * * * * * * * * * * * * * * *\n");
for(int i=0;i<3;i++)
{
ulIn = 1024;
if(i == 2)
{//PAD
ulIn = 1000;
}
for(register CK_ULONG i0 = 0;i0<ulIn;i0++)
bIn[i0] = (CK_BYTE)i0;
SHOW_INFO("\n");
SHOW_INFO("\nAES: C_EncryptUpdate/C_DecryptUpdate: \n");
SHOW_INFO(bHint[i]);
//ecnrypt init:
CK_BYTE iv[16] = {'*','2','1','0','4','z','y','b','*','2','1','0','4','z','y','b'};
CK_MECHANISM ckMechanism = {Mechanism[i], iv, sizeof(iv)};
START_OP("Encrypting initialize.")
CK_RV rv = m_gToken->C_EncryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv)
CK_ULONG ulEncrypted = 0;
START_OP("Encrypt the message.");
//invoked twice:
const CK_ULONG ulEnc1stPice = 33;
rv = m_gToken->C_EncryptUpdate(hSession, bIn, ulEnc1stPice, NULL, &ulTemp);//get buffer's size.
rv = m_gToken->C_EncryptUpdate(hSession, bIn, ulEnc1stPice, bTemp, &ulTemp);
//}}}
CheckRV("C_Encrypt[get buffer's size]", rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
//encrypt:
//invoked twice:
rv = m_gToken->C_EncryptUpdate(hSession, &(bIn[ulEnc1stPice]), ulIn-ulEnc1stPice, NULL, &ulTemp);//get buffer's size.
rv = m_gToken->C_EncryptUpdate(hSession, &(bIn[ulEnc1stPice]), ulIn-ulEnc1stPice, &(bTemp[ulEncrypted]), &ulTemp);
CheckRV("C_Encrypt", rv);
CHECK_OP(rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
START_OP("C_EncryptFinal...");
rv = m_gToken->C_EncryptFinal(hSession, NULL, &ulTemp);//Get buffer's size:
rv = m_gToken->C_EncryptFinal(hSession, &(bTemp[ulEncrypted]), &ulTemp);
CHECK_OP(rv);
ulEncrypted+=ulTemp;
ulTemp = 0;
SHOW_INFO("Data encrypted: \n");
ShowData(bTemp, ulEncrypted);
START_OP("Decrypting initialize.");
rv = m_gToken->C_DecryptInit(hSession, &ckMechanism, m_hKey);
CHECK_OP(rv);
START_OP("Decrypt the message.");
CK_ULONG ulDecrypt = 0;
const CK_ULONG ulDec1stPice = 17;
rv = m_gToken->C_DecryptUpdate(hSession, bTemp, ulDec1stPice, NULL, &ulOut);//Get buffer's size
rv = m_gToken->C_DecryptUpdate(hSession, bTemp, ulDec1stPice, bOut, &ulOut);
ulDecrypt +=ulOut;
ulOut = 0;
//Get decrypted data:
rv = m_gToken->C_DecryptUpdate(hSession, &(bTemp[ulDec1stPice]), ulEncrypted-ulDec1stPice, NULL, &ulOut);//Get buffer's size
rv = m_gToken->C_DecryptUpdate(hSession, &(bTemp[ulDec1stPice]), ulEncrypted-ulDec1stPice, &(bOut[ulDecrypt]), &ulOut);
CHECK_OP(rv);
ulDecrypt +=ulOut;
ulOut = 0;
START_OP("C_DecryptFinale...");
rv = m_gToken->C_DecryptFinal(hSession, NULL, &ulOut);//Get buffer's size
rv = m_gToken->C_DecryptFinal(hSession, &(bOut[ulDecrypt]), &ulOut);
CHECK_OP(rv);
ulDecrypt +=ulOut;
SHOW_INFO("Data decrypted: \n");
ShowData(bOut, ulDecrypt);
START_OP("Compare the original message and decrypted data: ");
if(0 == memcmp(bIn, bOut, ulDecrypt))
{
CHECK_OP(CKR_OK);
}
else
{
SHOW_INFO("....[FAILED]\n");
}
}
}
2.龙脉密码钥匙驱动实例工具等\mToken-GM3000\pkcs11\windows\samples\PKCStest\PKCStest.sln
/*
[]=========================================================================[]
FILE:
getinfos.cpp
DESC:
[]=========================================================================[]
*/
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "getinfos.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define PKCS_LIB_NAME "gm3000_pkcs11.dll"
//Initialize the token Cryptoki library:
CGetInfos::CGetInfos():m_hDll(NULL_PTR)
{
m_path = PKCS_LIB_NAME;
}
//Free the token Cryptoki library:Finish.
CGetInfos::~CGetInfos()
{
//if load library failed ,but m_pToke is NULL, so call C_Finalize will be wrong
if(m_pToken != NULL)
{
m_pToken->C_Finalize(NULL_PTR);
m_pToken = NULL_PTR;
}
if(m_hDll)
{
FreeLibrary(m_hDll);
}
}
unsigned long CGetInfos::GetSlotInfos(CK_SLOT_INFO_PTR pSlotInfo)
{
CK_RV rv = CKR_OK;
CK_ULONG ulCount = 0;
CK_SLOT_ID_PTR pSlotList = NULL_PTR;
rv = m_pToken->C_GetSlotList(FALSE, NULL_PTR, &ulCount);
if((rv != CKR_OK) || (ulCount <= 0))
return CKR_DEVICE_ERROR;
pSlotList = (CK_SLOT_ID_PTR)new CK_SLOT_ID [ulCount];
if (pSlotList == NULL_PTR)
{
return CKR_HOST_MEMORY;
}
rv = m_pToken->C_GetSlotList(FALSE, pSlotList, &ulCount);
if((rv != CKR_OK) || (ulCount <= 0))
{
delete [] pSlotList;
pSlotList = NULL_PTR;
return CKR_SLOT_ID_INVALID;
}
/*Get slot information for the first slot*/
for (unsigned int i = 0; i < ulCount; ++i)
{
rv = m_pToken->C_GetSlotInfo(pSlotList[i], pSlotInfo);
if(rv != CKR_OK)
{
delete [] pSlotList;
pSlotList = NULL_PTR;
return CKR_FUNCTION_FAILED;
}
//ShowSlotInfo(pSlotInfo);
}
delete [] pSlotList;
pSlotList = NULL_PTR;
return CKR_OK;
}
unsigned long CGetInfos::GetTokenInfos(CK_TOKEN_INFO_PTR pTokenInfo)
{
CK_RV rv = CKR_OK;
CK_ULONG ulCount = 0;
CK_SLOT_ID_PTR pSlotList = NULL_PTR;
rv = m_pToken->C_GetSlotList(TRUE, NULL_PTR, &ulCount);
if((rv != CKR_OK) || (ulCount <= 0))
return CKR_DEVICE_ERROR;
pSlotList = (CK_SLOT_ID_PTR)new CK_SLOT_ID [ulCount];
rv = m_pToken->C_GetSlotList(TRUE, pSlotList, &ulCount);
if((rv != CKR_OK) || (ulCount <= 0))
{
delete [] pSlotList;
pSlotList = NULL_PTR;
return CKR_TOKEN_NOT_PRESENT;
}
/*Get slot information for the first token*/
for (unsigned int i = 0; i < ulCount; ++i)
{
rv = m_pToken->C_GetTokenInfo(pSlotList[i], pTokenInfo);
if(rv != CKR_OK)
{
delete [] pSlotList;
pSlotList = NULL_PTR;
return CKR_FUNCTION_FAILED;
}
//ShowTokenInfo(pTokenInfo);
}
delete [] pSlotList;
pSlotList = NULL_PTR;
return CKR_OK;
}
bool CGetInfos::CheckRV(const char* szInfo, unsigned long rv)
{
printf(szInfo);
if(CKR_OK == rv)
{
//printf(" ... OK.\n");
return true;
}
printf(" ... FAILED. ");
switch(rv)
{
case CKR_SLOT_ID_INVALID:
printf("[CKR_SLOT_ID_INVALID]");
break;
case CKR_TOKEN_NOT_PRESENT:
printf("[CKR_TOKEN_NOT_PRESENT]");
break;
case CKR_FUNCTION_FAILED:
printf("[CKR_FUNCTION_FAILED]");
break;
case CKR_DEVICE_ERROR:
printf("[CKR_DEVICE_ERROR]");
break;
case CKR_HOST_MEMORY:
printf("[CKR_HOST_MEMORY]");
break;
default:
printf("[Unknown ERROR: 0x%08X]", rv);
}
printf("\n");
return false;
}
void CGetInfos::ShowSlotInfo(CK_SLOT_INFO_PTR slotinfo)
{
printf("\nSlot information:\n");
char DescBuffer[65] = {0};
memcpy(DescBuffer,slotinfo->slotDescription,64);
DescBuffer[64] = 0;
int i = 0;
for(i = 63; i > 0; --i)
if(' ' == DescBuffer[i])
DescBuffer[i] = '\0';
else
break;
printf("\tSlotDescription = %s\n", DescBuffer);
char manuBuffer[33] = {0};
memcpy(manuBuffer,slotinfo->manufacturerID,32);
manuBuffer[32] = 0;
for(i = 31; i > 0; --i)
if(' ' == manuBuffer[i])
manuBuffer[i] = '\0';
else
break;
printf("\tManufacturerID = %s\n", manuBuffer);
printf("\tFlags = %08X\n", slotinfo->flags);
printf("\tFirmwareVersion.major = %d\n", slotinfo->firmwareVersion.major);
printf("\tFirmwareVersion.minor = %d\n", slotinfo->firmwareVersion.minor);
printf("\tHardwareVersion.major = %d\n", slotinfo->hardwareVersion.major);
printf("\tHardwareVersion.minor = %d\n\n", slotinfo->hardwareVersion.minor);
}
void CGetInfos::ShowTokenInfo(CK_TOKEN_INFO_PTR tokenInfo)
{
printf("\nToken information:\n");
char label[33] = {0};
memcpy(label, tokenInfo->label, 32);
printf("\tLabel = %s\n", label);
char manuBuffer[33] = {0};
memcpy(manuBuffer,tokenInfo->manufacturerID,32);
manuBuffer[32] = 0;
printf("\tManufacturerID = %s\n", manuBuffer);
char modelBuffer[17] = {0};
memcpy(modelBuffer,tokenInfo->model,16);
manuBuffer[16] = 0;
printf("\tModel = %s\n", modelBuffer);
char SNBuffer[17] = {0};
memcpy(SNBuffer,tokenInfo->serialNumber,16);
manuBuffer[16] = 0;
printf("\tSerialNumber = %s\n", SNBuffer);
printf("\tFlags = 0x%08X\n", tokenInfo->flags);
printf("\tulMaxSessionCount = %d\n", tokenInfo->ulMaxSessionCount);
printf("\tulSessionCount = %d\n", tokenInfo->ulSessionCount);
printf("\tulMaxRwSessionCount = %d\n",tokenInfo->ulMaxRwSessionCount);
printf("\tulRwSessionCount = %d\n",tokenInfo->ulRwSessionCount);
printf("\tulMaxPinLen = %d\n",tokenInfo->ulMaxPinLen);
printf("\tulMinPinLen = %d\n",tokenInfo->ulMinPinLen);
printf("\tulTotalPublicMemory = %d\n", tokenInfo->ulTotalPublicMemory);
printf("\tulTotalPrivateMemory = %d\n", tokenInfo->ulTotalPrivateMemory);
printf("\tulFreePublicMemory = %d\n", tokenInfo->ulFreePublicMemory);
printf("\tulFreePrivateMemory = %d\n", tokenInfo->ulFreePrivateMemory);
printf("\tHardwareVersion.major = %d\n", tokenInfo->hardwareVersion.major);
printf("\tHardwareVersion.minor = %d\n", tokenInfo->hardwareVersion.minor);
printf("\tFirmwareVersion.major = %d\n", tokenInfo->firmwareVersion.major);
printf("\tFirmwareVersion.minor = %d\n", tokenInfo->firmwareVersion.minor);
printf("\tToken utcTime = %d\n", 0);
}
unsigned long CGetInfos::GetCryptokiInfos(CK_INFO_PTR pInfo)
{
memset(pInfo, 0, sizeof(pInfo));
if(m_pToken->C_GetInfo(pInfo) != CKR_OK)
{
return CKR_FUNCTION_FAILED;
}
return CKR_OK;
}
void CGetInfos::ShowCryptokiInfos(CK_INFO_PTR pInfo)
{
printf("\nCryptoki informations:\n");
printf("\tCryptokiVersion.major = %d\n", pInfo->cryptokiVersion.major);
printf("\tCryptokiVersion.minor = %d\n", pInfo->cryptokiVersion.minor);
printf("\tLibraryVersion.major = %d\n", pInfo->libraryVersion.major);
printf("\tLibraryVersion.minor = %d\n", pInfo->libraryVersion.minor);
printf("\tFlags = 0x%08X\n", pInfo->flags);
char LibDescBuffer[33] = {0};
memcpy(LibDescBuffer,pInfo->libraryDescription,32);
LibDescBuffer[32] = 0;
printf("\tLibraryDescription = %s\n", LibDescBuffer);
char manuBuffer[33] = {0};
memcpy(manuBuffer,pInfo->manufacturerID,32);
manuBuffer[32] = 0;
printf("\tManufacturerID = %s\n\n", manuBuffer);
}
bool CGetInfos::LoadLib()
{
#if defined(WIN32)
m_hDll = LoadLibrary(m_path);
#else
m_hDll = dlopen(m_path, RTLD_NOW);
#endif
if(m_hDll == NULL_PTR)
{
printf("Load Library Error!");
return false;
}
typedef CK_RV (* C_GETFUNCTIONLISTPROC)(CK_FUNCTION_LIST_PTR_PTR);
C_GETFUNCTIONLISTPROC pC_GetFunctionList = (C_GETFUNCTIONLISTPROC)GetProcAddress(m_hDll,"C_GetFunctionList");
if(pC_GetFunctionList == NULL_PTR)
{
printf("Get function list failed.\n");
return false;
}
if(CKR_OK!=pC_GetFunctionList(&m_pToken))
{
printf("Get function list failed.\n");
return false;
}
if(CKR_OK != m_pToken->C_Initialize(NULL_PTR))
{
printf("Call C_Initialize failed.\n");
return false;
}
return true;
}
/*
[]=========================================================================[]
FILE:
getusbinfos.cpp
DESC:
[]=========================================================================[]
*/
#include "stdafx.h"
#include "getinfos.h"
int main(int argc, char* argv[])
{
CGetInfos inf;
if(!inf.LoadLib())
return 0;
unsigned long rv;
CK_INFO cryptinfo;
rv = inf.GetCryptokiInfos(&cryptinfo);
if(inf.CheckRV("Get cryptoki library information", rv))
inf.ShowCryptokiInfos(&cryptinfo);
CK_SLOT_INFO slotInfo;
rv = inf.GetSlotInfos(&slotInfo);
if(inf.CheckRV("Get slot information", rv))
inf.ShowSlotInfo(&slotInfo);
CK_TOKEN_INFO tokeninfo;
rv = inf.GetTokenInfos(&tokeninfo);
if(inf.CheckRV("Get token information", rv))
inf.ShowTokenInfo(&tokeninfo);
printf("Press any key to continue...\n");
_getch();
return 0;
}
#include "pkcs11lib.h"
#include <windows.h>
HMODULE hPkcs11Lib = 0;
PKCS11Wraper PKCS11;
long Pkcs11Initialize(char * libName)
{
CK_RV result;
if (hPkcs11Lib != NULL)
return 0;
hPkcs11Lib = LoadLibrary(libName);
if(hPkcs11Lib == 0)
return 1;
CK_FUNCTION_LIST_PTR functions;
PKCS11.C_GetFunctionList = (CK_C_GetFunctionList)GetProcAddress(hPkcs11Lib,"C_GetFunctionList");
result = PKCS11.C_GetFunctionList(&functions);
if (result != CKR_OK)
return result;
PKCS11.C_Initialize = functions->C_Initialize;
PKCS11.C_Finalize = functions->C_Finalize;
PKCS11.C_GetInfo = functions->C_GetInfo;
PKCS11.C_GetFunctionList = functions->C_GetFunctionList;
PKCS11.C_GetSlotList = functions->C_GetSlotList;
PKCS11.C_GetSlotInfo = functions->C_GetSlotInfo;
PKCS11.C_GetTokenInfo = functions->C_GetTokenInfo;
PKCS11.C_GetMechanismList = functions->C_GetMechanismList;
PKCS11.C_GetMechanismInfo = functions->C_GetMechanismInfo;
PKCS11.C_InitToken = functions->C_InitToken;
PKCS11.C_InitPIN = functions->C_InitPIN;
PKCS11.C_SetPIN = functions->C_SetPIN;
PKCS11.C_OpenSession = functions->C_OpenSession;
PKCS11.C_CloseSession = functions->C_CloseSession;
PKCS11.C_CloseAllSessions = functions->C_CloseAllSessions;
PKCS11.C_GetSessionInfo = functions->C_GetSessionInfo;
PKCS11.C_GetOperationState = functions->C_GetOperationState;
PKCS11.C_SetOperationState = functions->C_SetOperationState;
PKCS11.C_Login = functions->C_Login;
PKCS11.C_Logout = functions->C_Logout;
PKCS11.C_CreateObject = functions->C_CreateObject;
PKCS11.C_CopyObject = functions->C_CopyObject;
PKCS11.C_DestroyObject = functions->C_DestroyObject;
PKCS11.C_GetObjectSize = functions->C_GetObjectSize;
PKCS11.C_GetAttributeValue = functions->C_GetAttributeValue;
PKCS11.C_SetAttributeValue = functions->C_SetAttributeValue;
PKCS11.C_FindObjectsInit = functions->C_FindObjectsInit;
PKCS11.C_FindObjects = functions->C_FindObjects;
PKCS11.C_FindObjectsFinal = functions->C_FindObjectsFinal;
PKCS11.C_EncryptInit = functions->C_EncryptInit;
PKCS11.C_Encrypt = functions->C_Encrypt;
PKCS11.C_EncryptUpdate = functions->C_EncryptUpdate;
PKCS11.C_EncryptFinal = functions->C_EncryptFinal;
PKCS11.C_DecryptInit = functions->C_DecryptInit;
PKCS11.C_Decrypt = functions->C_Decrypt;
PKCS11.C_DecryptUpdate = functions->C_DecryptUpdate;
PKCS11.C_DecryptFinal = functions->C_DecryptFinal;
PKCS11.C_DigestInit = functions->C_DigestInit;
PKCS11.C_Digest = functions->C_Digest;
PKCS11.C_DigestUpdate = functions->C_DigestUpdate;
PKCS11.C_DigestKey = functions->C_DigestKey;
PKCS11.C_DigestFinal = functions->C_DigestFinal;
PKCS11.C_SignInit = functions->C_SignInit;
PKCS11.C_Sign = functions->C_Sign;
PKCS11.C_SignUpdate = functions->C_SignUpdate;
PKCS11.C_SignFinal = functions->C_SignFinal;
PKCS11.C_SignRecoverInit = functions->C_SignRecoverInit;
PKCS11.C_SignRecover = functions->C_SignRecover;
PKCS11.C_VerifyInit = functions->C_VerifyInit;
PKCS11.C_Verify = functions->C_Verify;
PKCS11.C_VerifyUpdate = functions->C_VerifyUpdate;
PKCS11.C_VerifyFinal = functions->C_VerifyFinal;
PKCS11.C_VerifyRecoverInit = functions->C_VerifyRecoverInit;
PKCS11.C_VerifyRecover = functions->C_VerifyRecover;
PKCS11.C_DigestEncryptUpdate = functions->C_DigestEncryptUpdate;
PKCS11.C_DecryptDigestUpdate = functions->C_DecryptDigestUpdate;
PKCS11.C_SignEncryptUpdate = functions->C_SignEncryptUpdate;
PKCS11.C_DecryptVerifyUpdate = functions->C_DecryptVerifyUpdate;
PKCS11.C_GenerateKey = functions->C_GenerateKey;
PKCS11.C_GenerateKeyPair = functions->C_GenerateKeyPair;
PKCS11.C_WrapKey = functions->C_WrapKey;
PKCS11.C_UnwrapKey = functions->C_UnwrapKey;
PKCS11.C_DeriveKey = functions->C_DeriveKey;
PKCS11.C_SeedRandom = functions->C_SeedRandom;
PKCS11.C_GenerateRandom = functions->C_GenerateRandom;
PKCS11.C_GetFunctionStatus = functions->C_GetFunctionStatus;
PKCS11.C_CancelFunction = functions->C_CancelFunction;
PKCS11.C_WaitForSlotEvent = functions->C_WaitForSlotEvent;
result = PKCS11.C_Initialize(NULL_PTR);
if (result != CKR_OK)
{
FreeLibrary(hPkcs11Lib);
hPkcs11Lib = NULL;
}
return result;
}
PKCS11Wraper * GetPkcs11Wrapper()
{
return &PKCS11;
}
// stdafx.cpp : source file that includes just the standard includes
// GetUSBInfos.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
四、任务四
0 2人一组,创建一个文件,文件名为小组成员学号,内容为小组成员学号和姓名
1 在Ubuntu中使用OpenSSL用SM4算法加密上述文件,然后用龙脉eKey解密,提交代码和运行结果截图
2 在Ubuntu中基于OpenSSL产生一对公私钥对(SM2算法)
3 在Ubuntu中使用OpenSSL用SM3算法计算上述文件的Hash值,然后用OpenSSL SM2算法计算Hash值的签名,用龙脉eKey进行验签,提交代码和运行结果截图
4 加分项:在Windows中重现上述过程
在Ubuntu中使用OpenSSL用SM4算法加密上述文件,然后用龙脉eKey解密
1.openssl SM4加密
openssl enc -sm4 -in 20201212-20201220.txt -out encrypt.txt -pass pass:12345
2.openssl SM4解密
openssl enc -d -sm4 -in encrypt.txt -out decrypt.txt -pass pass:12345
3.gmssl解密
gmssl enc -sms4 -d -in encrypt.txt -out decryptGM.txt -pass pass:12345
在Ubuntu中基于OpenSSL产生一对公私钥对(SM2算法)
到openssl的apps文件夹下,输入命令如下所示:
./openssl ecparam -genkey -name SM2 -out priv.key
./openssl ec -in priv.key -pubout -out pub.key
./openssl ecparam -genkey -name SM2 -out all.key
在Ubuntu中使用OpenSSL用SM3算法计算上述文件的Hash值,然后用OpenSSL SM2算法计算Hash值的签名,用龙脉eKey进行验签
(一)使用OpenSSL用SM3算法计算上述文件的Hash值
openssl dgst -sm3 20201212-20201220.txt
openssl sm3 -binary -out dgst.txt 20201212-20201220.txt
3b28c5acf24eb2419f0cae47f7509ab7a553e275f59070017bd37ca2700d6c12
(二)用sm2的公私钥对进行签名、验签:
openssl pkeyutl -sign -inkey all.key -in dgst.txt -out signature.bin
openssl pkeyutl -verify -in dgst.txt -sigfile signature.bin -inkey all.key
(三)Gmssl下证书的生成
http://www.javashuo.com/article/p-ejpehuti-u.html
https://blog.csdn.net/weixin_30877227/article/details/97106010
1.生成SM2密钥对
gmssl sm2 -genkey -out cakeyGM.pem
2.生成SM2自签名证书
gmssl req -new -x509 -key cakeyGM.pem -out cacertGM.crt
3.生成SM2用户密钥对
gmssl sm2 -genkey -out uGM.com.key
4.生成证书请求csr
gmssl req -new -key uGM.com.key -out uGM.com.csr
5.用CA进行签名
gmssl ca -in uGM.com.csr -out uGM.com.crt -cert cacertGM.crt -keyfile cakeyGM.pem
6.验证签名
gmssl verify -verbose -x509_strict -CAfile cacertGM.crt uGM.com.crt
7.生成证书文件
gmssl pkcs12 -export -in cacertGM.crt -inkey cakeyGM.pem -out lhRootCA.p12
加分项:在Windows中重现上述过程
问题及解决
1.运行不了openssl sm2 -sign private_key.pem -in dgst.txt -out signature.bin
如果您在命令行中输入openssl sm2 -sign private_key.pem -in dgst.txt -out signature.bin
,会显示以下错误信息:
Error: 'sm2' is an invalid command.
这是因为OpenSSL并没有提供名为“sm2”的单独命令。SM2算法可以与其他命令一起使用,例如:openssl dgst
和openssl pkeyutl
等。
要使用SM2签名,请使用以下命令:
openssl dgst -sm3 -sign private_key.pem -out signature.bin dgst.txt
其中,-sm3
指定使用SM3哈希算法进行摘要计算,-sign private_key.pem
指定使用private_key.pem文件中的私钥进行签名,-out signature.bin
指定输出签名结果到signature.bin文件中,最后的dgst.txt
是待签名的数据文件。
五、心得体会
在本次实验中,我们学习了 OpenSSL 的编译与安装、龙脉密码钥匙驱动实例工具的使用、常见密码引擎 API 的规范和标准以及 SM2、SM3、SM4 等密码算法的调用和使用方法。通过实验,我们深入了解了密码引擎开发的过程和技巧,并对密码学的知识有了更深入的理解。同时,我们也体会到了在实际开发过程中,合理的应用密码引擎可以大大提高系统的安全性和可靠性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义