⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encsigntest.cpp

📁 csp application specifiescsp app lication specifiescsp app lication specifies
💻 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 + -