📄 encsigntest.cpp
字号:
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <conio.h>
#include "csp-debug.h"
UCHAR PubBlobData[1024];
DWORD PubBlobLen;
//const char conname[]="3589cfb2-e7c9-4c77-8972-9796ff463eb3";
char conname[1024];
char strBuffer[1024];
void Reverse(LPBYTE buf, size_t len)
{
size_t pos, maxPos = len / 2 - 1;
for (pos = 0; pos <= maxPos; pos++)
{
char temp;
temp = buf[pos];
buf[pos] = buf[len - 1 - pos];
buf[len - 1 - pos] = temp;
}
}
/*
函数功能: RSA签名(使用三环的CSP)
输入参数: SrcData 需签名的数据
SrcLen 需签名的数据长度
输出参数: DstData 签名后的数据
DstLen 签名后的数据长度
返回值: 成功返回0,失败返回-1
*/
int myCspSignData(BYTE *SrcData,DWORD SrcLen,BYTE *DstData,DWORD *DstLen)
{
BOOL rslt; //存放函数返回
HCRYPTPROV hProv; //CSP句柄
HCRYPTPROV hProv1;
HCRYPTKEY hKey; //证书私钥句柄
HCRYPTHASH hHash; //哈希对象句柄
HCRYPTHASH hHash1;
BYTE *pbSignature; //指向签名值的指针
DWORD dwSigLen;
//打开容器
rslt = CryptAcquireContext( &hProv,
conname,//"7b5f2fc0-2171-4541-b88d-2b9c0c7a698b",//6906618f-5655-43dc-96a1-4fe334fc8808", //容器名
"OlymTech Cryptographic Service Provider", //CSP名称
PROV_RSA_FULL,
CRYPT_SILENT);
if(!rslt)
{
DEBUG(0,"无法打开容器");
goto end;
}
#if 1
if(CryptSetProvParam(
hProv,
PP_KEYEXCHANGE_PIN,
(BYTE*)"1234",
0))
{
//printf("CryptSetProvParam succeeded.\n");
}
else
{
printf("Error during CryptSetProvParam.");
}
#endif
//获取签名私钥对
rslt = CryptGetUserKey(hProv, AT_SIGNATURE, &hKey);
if(!rslt)
{
DEBUG(0,"无法获取签名私钥");
goto end;
}
//begin
//导出公钥-获取长度
rslt = CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0, NULL, &PubBlobLen);
if(!rslt)
{
DEBUG(0,"导出公钥失败");
goto end;
}
//导出公钥-获取数据
rslt = CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0, PubBlobData,&PubBlobLen);
if(!rslt)
{
DEBUG(0,"导出公钥失败");
goto end;
}
//创建哈希对象,使用CALG_SHA1算法
rslt = CryptCreateHash(hProv,CALG_SHA1,0, 0, &hHash);
if(!rslt)
{
DEBUG(0,"创建哈希对象失败");
goto end;
}
//计HASH
rslt = CryptHashData(hHash, NULL, 0, 0);
if(!rslt)
{
DEBUG(0,"计算哈希失败");
goto end;
}
//进行签名操作
dwSigLen= 0;
//取得签名数据长度
rslt = CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSigLen);
if(!rslt)
{
DEBUG(0,"获取签名数据长度失败");
goto end;
}
//分配内存
pbSignature = (BYTE *)malloc(dwSigLen);
if(!pbSignature)
{
DEBUG(0,"申请内存失败");
goto end;
}
//使用类型为AT_SIGNATURE的密钥对上文获得的哈希值进行签名
rslt = CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pbSignature, &dwSigLen);
if(!rslt)
{
DEBUG(0,"签名失败");
goto end;
}
memcpy(DstData,pbSignature,dwSigLen);
free(pbSignature);
*DstLen=dwSigLen;
CryptDestroyHash(hHash);
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
return 0;
end:
CryptReleaseContext(hProv, 0);
return -1;
}
/*
函数功能: RSA验签(使用微软的CSP)
输入参数: SrcData 需签名的数据
SrcLen 需签名的数据长度
输出参数: DstData 签名后的数据
DstLen 签名后的数据长度
返回值: 成功返回0,失败返回-1
*/
int myCspVefifyData(BYTE *SrcData,DWORD SrcLen,BYTE *DstData,DWORD DstLen)
{
BOOL rslt; //存放函数返回
HCRYPTPROV hProv; //CSP句柄
HCRYPTKEY hKey; //证书私钥句柄
HCRYPTHASH hHash; //哈希对象句柄
BYTE *pbSignature; //指向签名值的指针
DWORD dwSigLen;
//打开容器
rslt = CryptAcquireContext(&hProv,
"zxb201",
"Microsoft Enhanced Cryptographic Provider v1.0",
PROV_RSA_FULL,
CRYPT_NEWKEYSET);
if(!rslt)
{
rslt = CryptAcquireContext(&hProv,
NULL,
"Microsoft Enhanced Cryptographic Provider v1.0",
PROV_RSA_FULL,
0);
if(!rslt)
{
DEBUG(0,"无法打开容器");
goto end;
}
rslt = CryptGenKey(hProv,AT_KEYEXCHANGE,CRYPT_EXPORTABLE,&hKey);
if(!rslt)
{
DEBUG(0,"生成密钥对失败");
goto end;
}
}
//导入公钥
rslt = CryptImportKey(hProv,PubBlobData,sizeof(PubBlobData),0,0,&hKey);
if(!rslt)
{
DEBUG(0,"导入公钥失败");
goto end;
}
//创建哈希对象,使用CALG_SHA1算法
rslt = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
if(!rslt)
{
DEBUG(0,"创建哈希对象失败");
goto end;
}
//计算HASH
rslt = CryptHashData(hHash, SrcData, SrcLen, 0);
if(!rslt)
{
DEBUG(0,"计算哈希失败");
goto end;
}
pbSignature=(unsigned char *)malloc(DstLen);
memcpy(pbSignature,DstData,DstLen);
dwSigLen=DstLen;
//验签
rslt = CryptVerifySignature(hHash, pbSignature, dwSigLen, hKey, NULL, 0);
if(!rslt)
{
DEBUG(0,"验签失败");
goto end;
}
CryptDestroyHash(hHash);
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
free(pbSignature);
return 0;
end:
CryptReleaseContext(hProv, 0);
return -1;
}
/*
函数功能: RSA加密(使用微软的CSP)
输入参数: SrcData 需加密的数据
SrcLen 需加密的数据长度
输出参数: DstData 加密后的数据
DstLen 加密后的数据长度
返回值: 成功返回0,失败返回-1
*/
int myCspEncryptData(BYTE *SrcData,DWORD SrcLen,BYTE *DstData,DWORD *DstLen)
{
BOOL rslt; //存放函数返回
HCRYPTPROV hProv; //CSP句柄
HCRYPTKEY hKey; //证书私钥句柄
unsigned char pData[512] = {0};
memcpy(pData,SrcData,SrcLen);
unsigned long ulDataLen = SrcLen;
unsigned long ulEncryptedLen=ulDataLen;
unsigned char* pOut;
//打开容器
rslt = CryptAcquireContext(&hProv,
NULL,
"Microsoft Enhanced Cryptographic Provider v1.0",
PROV_RSA_FULL,
CRYPT_NEWKEYSET);
if(!rslt)
{
rslt = CryptAcquireContext(&hProv,
NULL,
"Microsoft Enhanced Cryptographic Provider v1.0",
PROV_RSA_FULL,
0);
if(!rslt)
{
DEBUG(0,"无法打开容器");
goto end;
}
}
rslt = CryptGenKey(hProv,AT_KEYEXCHANGE,CRYPT_EXPORTABLE,&hKey);
if(!rslt)
{
DEBUG(0,"生成密钥对失败");
goto end;
}
//获取加密密钥对
rslt = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey);
if(!rslt)
{
DEBUG(0,"获取密钥对失败");
goto end;
}
//导入公钥
rslt = CryptImportKey(hProv,PubBlobData,sizeof(PubBlobData),0,0,&hKey);
if(!rslt)
{
DEBUG(0,"导入公钥失败");
goto end;
}
//加密-获取加密长度
if(!CryptEncrypt(hKey, 0, TRUE, 0, NULL, &ulEncryptedLen, ulDataLen))
{
DEBUG(0,"获取加密长度失败");
goto end;
}
pOut =(unsigned char *)malloc(ulEncryptedLen);
memset(pOut, 0, ulEncryptedLen);
memcpy(pOut, pData, ulDataLen);
ulDataLen=ulEncryptedLen;
ulEncryptedLen=SrcLen;
//加密
if(!CryptEncrypt(hKey, 0, TRUE, 0, pOut, &ulEncryptedLen, ulDataLen))
{
DEBUG(0,"加密失败");
goto end;
}
*DstLen=ulEncryptedLen;
memcpy(DstData,pOut,ulEncryptedLen);
free(pOut);
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
return 0;
end:
CryptReleaseContext(hProv, 0);
return -1;
}
/*
函数功能: RSA解密(使用三环的CSP)
输入参数: SrcData 需解密的数据
SrcLen 需解密的数据长度
输出参数: DstData 解密后的数据
DstLen 解密后的数据长度
返回值: 成功返回0,失败返回-1
*/
int myCspDecryptData(BYTE *SrcData,DWORD SrcLen,BYTE *DstData,DWORD *DstLen)
{
BOOL rslt; //存放函数返回
HCRYPTPROV hProv; //CSP句柄
HCRYPTKEY hKey; //证书私钥句柄
unsigned char tempData[512];
DWORD tempLen;
memset(tempData,0,sizeof(tempData));
memcpy(tempData,SrcData,SrcLen);
tempLen=SrcLen;
//打开容器
rslt = CryptAcquireContext( &hProv,
conname,//"7b5f2fc0-2171-4541-b88d-2b9c0c7a698b",//6906618f-5655-43dc-96a1-4fe334fc8808", //容器名
"OlymTech Cryptographic Service Provider",//CSP名称
PROV_RSA_FULL,
CRYPT_SILENT);
if(!rslt)
{
DEBUG(0,"无法打开容器");
goto end;
}
#if 1
if(CryptSetProvParam(
hProv,
PP_KEYEXCHANGE_PIN,
(BYTE*)"1234",
0))
{
//printf("CryptSetProvParam succeeded.\n");
}
else
{
printf("Error during CryptSetProvParam.");
}
#endif
//获取加密密钥对
rslt = CryptGetUserKey( hProv,
AT_KEYEXCHANGE,
&hKey);
if(!rslt)
{
DEBUG(0,"无法获取密钥对");
goto end;
}
//解密
rslt = CryptDecrypt(hKey,
NULL,
TRUE,
NULL,
tempData,
&tempLen);
if(!rslt)
{
DEBUG(0,"解密失败");
goto end;
}
memcpy(DstData,tempData,tempLen);
*DstLen=tempLen;
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
return 0;
end:
CryptReleaseContext(hProv, 0);
return -1;
}
double get_time(void)
{
#ifndef WIN32
static clock_t last_clock = 0;
static double acc = 0;
clock_t this_clock;
double delta;
this_clock = clock();
if (last_clock == 0) {
delta = 0;
} else {
delta = (this_clock - last_clock)/((double)(CLOCKS_PER_SEC/1000));
if (delta < 0)
delta = 0;
}
acc += delta;
last_clock = this_clock;
return acc;
#else
static LARGE_INTEGER last_clock;
static double acc=0;
LARGE_INTEGER this_clock, timerFrequency;
double delta, tfreq;
QueryPerformanceFrequency(&timerFrequency);
tfreq = (double) timerFrequency.QuadPart;
QueryPerformanceCounter(&this_clock);
if(last_clock.QuadPart==0){
delta=0;
}
else{
delta=(this_clock.QuadPart - last_clock.QuadPart)/tfreq; //second
if(delta<0)
delta=0;
}
acc += delta;
last_clock = this_clock;
return acc;
#endif
}
void test_RegisterCert1()
{
BOOL rslt; //存放函数返回
HCRYPTPROV hProv; //CSP句柄
memset(conname,0,sizeof(conname));
rslt = CryptAcquireContext( &hProv,
NULL,
"OlymTech Cryptographic Service Provider",
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT);
DWORD cbName;
char pszName[255];
int i;
i=0;
//---------------------------------------------------------------
// Read the name of the key container.
cbName = 1000;
if(CryptGetProvParam(
hProv,
PP_ENUMCONTAINERS, //获取容器名字
(BYTE*)pszName,
&cbName,
CRYPT_FIRST))
{
printf("Key Container name: %s\n", pszName);
strcpy(conname,pszName);
}
CryptReleaseContext(hProv, 0);
}
int main()
{
int i;
int count=0;
int ret;
unsigned char SrcData[512];
DWORD SrcLen=128;
unsigned char DstData[512];
DWORD DstLen=0;
memset(SrcData,0,sizeof(SrcData));
unsigned char EncData[128];
unsigned char DecData[128];
DWORD EncLen=100;
DWORD DecLen;
double tm1;
double tm2;
tm1 = get_time();
test_RegisterCert1();
while(1)
{
count++;
for(i=0;i<128;i++)
{
SrcData[i]=(unsigned char)rand();
}
//签名
ret = myCspSignData(SrcData,SrcLen,DstData,&DstLen);
if(ret!=0)
{
printf("签名失败");
break;
}
//验证
ret = myCspVefifyData(SrcData,SrcLen,DstData,DstLen);
if(ret!=0)
{
printf("验证失败");
//break;
}
for(i=0;i<EncLen;i++)
{
EncData[i]=(unsigned char)rand();
}
//加密
ret = myCspEncryptData(EncData,EncLen,DstData,&DstLen);
if(ret!=0)
{
printf("加密失败");
//break;
}
//for(i=0;i<DstLen;i++)
//{
// printf("0x%02x,",DstData[i]);
//}
//解密
ret = myCspDecryptData(DstData,DstLen,DecData,&DecLen);
if(ret!=0)
{
printf("解密失败");
break;
}
//for(i=0;i<DecLen;i++)
//{
// printf("0x%02x,",DecData[i]);
//}
//printf("\n");
if(memcmp(EncData,DecData,EncLen)!=0)
{
break;
}
sprintf(strBuffer,"成功执行第%d个循环\n",count);
DEBUG(0,strBuffer);
printf("%s",strBuffer);
}
tm2 = get_time();
sprintf(strBuffer,"总共持续不出错时间:%f秒",tm2-tm1);
DEBUG(0,strBuffer);
getch();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -