CSP应用开发-签名和验签

31 篇文章 2 订阅
14 篇文章 12 订阅

下面代码实现了调用CSP实现数据的签名和验签,函数中有些细节没有处理好,但总体流程上应该是没有问题的,测试通过:

//本程序通过调用CSP实现签名及验签功能
#include "stdafx.h"
#include <windows.h>
#include <wincrypt.h>

#define IN
#define OUT

/*****************************************************
*函数名:SignHash
*功  能:对一段数据进行哈稀签名,并导出公钥
*入  参:IN BYTE* pData,        //欲进行哈稀签名的数据
		 IN DWORD dwDataLen,	//数据长度
*出  参:OUT BYTE** pSignature, //哈稀签名数据的地址,使用完后由调用者释放
		 OUT DWORD* dwSigLen,	//签名实际长度
		 OUT BYTE** pPublicKey, //公钥数据的地址,使用完后由调用者释放
		 OUT DWORD* dwPubKeyLen);//公钥实际长度
*返回值:BOOL,TRU为签名成功,FALSE为签名失败
******************************************************/
BOOL SignHash(IN BYTE* pData, IN DWORD dwDataLen, OUT BYTE** pSignature, OUT DWORD* dwSigLen, OUT BYTE** pPublicKey, OUT DWORD* dwPubKeyLen);

/*****************************************************
*函数名:VerifySignature
*功  能:对一段数据进行签名验证
*入  参:IN BYTE* pData,        //欲进行哈稀验证的数据
		 IN DWORD dwDataLen,	//数据长度
		 IN BYTE* pSignature,	//签名
		 IN DWORD dwSigLen,		//签名长度
		 IN BYTE* pPublicKey,	//公钥
		 IN DWORD dwPublicKeyLen);//公钥长度
*出  参:无
*返回值:BOOL,TRU为验证签名成功,FALSE为验证签名失败
******************************************************/
BOOL VerifySignature(IN BYTE* pData, IN DWORD dwDataLen, IN BYTE* pSignature, IN DWORD dwSigLen, IN BYTE* pPublicKey, IN DWORD dwPublicKeyLen);


int _tmain(int argc, CHAR* argv[])
{
	CHAR* pData = (CHAR*)"35704uoifhroqfoierfqqe7r89qre";
	BYTE* pSignature = NULL;
	DWORD dwSigLen = 0;
	BYTE* pPublicKey = NULL;
	DWORD dwPublicKeyLen = 0;
	SignHash((BYTE*)pData, strlen(pData),  &pSignature, &dwSigLen, &pPublicKey, &dwPublicKeyLen);
	
	printf("signature:%s, publickey:%s", pSignature, pPublicKey);

	VerifySignature((BYTE*)pData, strlen(pData), pSignature, dwSigLen, pPublicKey,dwPublicKeyLen);

	if(pPublicKey)
		free(pPublicKey);
	if(pSignature)
		free(pSignature);

	getchar();
	return 0;
}

BOOL SignHash(IN BYTE* pData, IN DWORD dwDataLen, OUT BYTE** pSignature, OUT DWORD* dwSigLen, OUT BYTE** pPublicKey, OUT DWORD* dwPubKeyLen)
{
	//一、获得一个CSP句柄
	HCRYPTPROV hCryptProv;
	BOOL bRet = CryptAcquireContext(
		&hCryptProv,
		NULL,			//密钥容器名,NULL表示使用默认容器
		NULL,			//CSP_NAME
		PROV_RSA_FULL,
		0
		);
	if(!bRet)
	{
		bRet = CryptAcquireContext(
			&hCryptProv,
			NULL,			//密钥容器名,NULL表示使用默认容器
			NULL,			//CSP_NAME
			PROV_RSA_FULL,
			CRYPT_NEWKEYSET //创建密钥容器
			);
		if(!bRet)
		{
			printf("CryptAcquireContext fail!");
			return FALSE;
		}
	}

	//二,获取签名密钥
	HCRYPTKEY hKey;
	bRet = CryptGetUserKey(hCryptProv,AT_SIGNATURE,&hKey);
	if(!bRet)
	{
		//获取失败,现在创建新的RSA密钥对。\n");   
		bRet = CryptGenKey(hCryptProv, 2, CRYPT_EXPORTABLE | 0X04000000, &hKey);
		if(!bRet)
		{
			printf("CryptGenKey fail!\n");
			return FALSE;
		}
	}

	//三、导出公钥
	if(CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, NULL, dwPubKeyLen))  
		printf("we get the length of the public key.\n");  
	else  
		printf("CryptExportKey erro.\n"); 

	if(*pPublicKey = (BYTE*)malloc(*dwPubKeyLen))  
		printf("we get the memory.\n");  
	else  
		printf("malloc erro.\n"); 

	if(CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, *pPublicKey,dwPubKeyLen))  
		printf("export the public key.\n");  
	else  
		printf("CryptExportKeya error.\n"); 

	//四、对数据进行哈稀签名
	HCRYPTHASH hHash;
	if(CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash))  
		printf("CreateHash succeed.\n");  
	else  
		printf("CreatHash error.\n");  

	if(CryptHashData(hHash, pData, dwDataLen, 0))  
		printf("HashData succeed.\n ");  
	else  
		printf("HashData error.\n");  
	//获取签名的长度
	if(CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, dwSigLen))  
		printf("Get the length of signature.\n");  
	else  
		printf("CryptSignHash error.\n");  
	if(*pSignature = (BYTE*) malloc(*dwSigLen))  
		printf("get the memory.\n");  
	else  
		printf("memory error.\n"); 
	//签名
	if(CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, *pSignature, dwSigLen))  
		printf("signature succeed.\n");  
	else 
	{
		printf("Signature error.\n"); 
		return FALSE;
	}
	
	if(hKey)
		CryptDestroyKey(hKey);
	if(hHash)
		CryptDestroyHash(hHash);
	if(hCryptProv)
		CryptReleaseContext(hCryptProv, 0);

	return TRUE;
}

BOOL VerifySignature(IN BYTE* pData, IN DWORD dwDataLen, IN BYTE* pSignature, IN DWORD dwSigLen, IN BYTE* pPublicKey, IN DWORD dwPublicKeyLen)
{
	//一、获得一个CSP句柄
	HCRYPTPROV hCryptProv;
	BOOL bRet = CryptAcquireContext(
		&hCryptProv,
		NULL,			//密钥容器名,NULL表示使用默认容器
		NULL,			//CSP_NAME
		PROV_RSA_FULL,
		0
		);
	if(!bRet)
	{
		bRet = CryptAcquireContext(
			&hCryptProv,
			NULL,			//密钥容器名,NULL表示使用默认容器
			NULL,			//CSP_NAME
			PROV_RSA_FULL,
			CRYPT_NEWKEYSET //创建密钥容器
			);
		if(!bRet)
		{
			printf("CryptAcquireContext fail!");
			return FALSE;
		}
	}

	//二、导入公钥
	HCRYPTKEY hPubKey;
	if(CryptImportKey(hCryptProv, pPublicKey, dwPublicKeyLen, 0, 0, &hPubKey))  
		printf("Import the key.\n");  
	else  
		printf("erro");  

	//计算哈稀
	HCRYPTHASH hHash;
	if(CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash))  
		printf("创建哈希对象成功 \n");  
	else  
		printf("调用CryptCreateHash失败"); 

	if(CryptHashData(hHash, pData, dwDataLen, 0))  
		printf("数据哈希完成.\n");  
	else  
		printf("调用CryptHashData失败");

	//验证哈稀签名
	if(CryptVerifySignature(hHash, pSignature, dwSigLen, hPubKey, NULL, 0))  
		printf("验证签名成功。\n");  
	else  
		printf("签名验证失败,签名无效");   

	if(hHash)  
		CryptDestroyHash(hHash);  
	if(hCryptProv)  
		CryptReleaseContext(hCryptProv,0);

	return TRUE;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值