/*********************************************************************************
* 函数名:signHash
* 功 能:对一段数据进行哈希签名,并导出公钥
* 参 数:CHAR pData(in) //想要进行哈希签名的数据
DWORD dwDataLen(in) //数据长度
BYTE **pSignature(out) //哈希签名数据的地址,使用完后由调用者释放
DWORD *dwSigLen(out) //签名实际长度
BYTE **pPublicKey(out) //公钥数据的地址,使用完后由调用者释放
DWORD *dePublicKeyLen(out) //公钥实长度
* 返回值:BOOL,TURE为签名成功,FALSE为签名失败
**********************************************************************************/
BOOL signHash(CHAR *pData,DWORD dwDataLen,BYTE **pSignature,DWORD *dwSigLen,BYTE **pPublicKey,DWORD *dwPublicKeyLen);
/*********************************************************************************
* 函数名:verifSignature
* 功 能:对一段数据进行签名验证
* 参 数:CHAR *pData(in) //想要进行哈希验证的数据
DWORD deDataLen(in) //数据长度
BYTE *pSignature(in) //签名
DWORD deSigLen //签名长度
BYTE *pPublicKey //公钥
DWORD dwPublicKeyLen //公钥长度
* 返回值:BOOL,TURE为验证签名成功,FALSE为验证签名失败
***********************************************************************************/
BOOL verifSignature(CHAR *pData,DWORD dwDataLen,BYTE *pSignature,DWORD dwSigLen,BYTE *pPublicKey,DWORD dwPublicKeyLen);
#include "stdafx.h"
#include "signature.h"
#include <wincrypt.h>
#include <iostream>
using namespace std;
int main()
{
CHAR* data = (CHAR*)"沈雪冰|18844438@qq.com||950420-***";
DWORD dataLen=strlen(data);
BYTE* pSignature = NULL;
DWORD dwSigLen = 0;
BYTE* pPublicKey = NULL;
DWORD dwPublicKeyLen = 0;
signHash(data, dataLen, &pSignature, &dwSigLen, &pPublicKey, &dwPublicKeyLen);
printf("-------------------------------------------------------------------------------------------\n");
printf("signature:%s\n\n publickey:%s\n", pSignature, pPublicKey);
printf("-------------------------------------------------------------------------------------------\n");
verifSignature(data, dataLen, pSignature, dwSigLen, pPublicKey,dwPublicKeyLen);
if(pPublicKey)
free(pPublicKey);
if(pSignature)
free(pSignature);
getchar();
return 0;
}
BOOL signHash(CHAR *pData,DWORD dwDataLen,BYTE **pSignature,DWORD *dwSigLen,BYTE **pPublicKey,DWORD *dwPublicKeyLen)
{
HCRYPTPROV hCryptProv;
BOOL res=CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,0);
if(!res)
{
res=CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,CRYPT_NEWKEYSET);
if(!res)
{
printf("创建CSP容器失败!\n");
return FALSE;
}
}
HCRYPTKEY hKey;
res=CryptGetUserKey(hCryptProv,AT_SIGNATURE,&hKey);
if(!res)
{
res=CryptGenKey(hCryptProv,2,CRYPT_EXPORTABLE|0X04000000,&hKey);
if(!res)
{
printf("创建RSA秘钥对失败!\n");
return FALSE;
}
}
if (CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0,NULL,dwPublicKeyLen))
printf("获取公钥长度成功!\n");
else
printf("获取公钥失败!\n");
if(*pPublicKey=(BYTE*)malloc(*dwPublicKeyLen))
printf("开辟公钥长度空间成功!\n");
else
printf("开辟公钥长度空间失败!\n");
if (CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0,*pPublicKey,dwPublicKeyLen))
printf("导出公钥成功!\n");
else
printf("导出公钥失败!\n");
HCRYPTHASH hHash;
if(CryptCreateHash(hCryptProv,CALG_SHA1,0,0,&hHash))
printf("创建哈希签名成功!\n");
else
printf("创建哈希签名失败!\n");
if(CryptHashData(hHash,(const BYTE *)pData,dwDataLen,0))
printf("将数据进行哈希成功!\n");
else
printf("将数据进行哈希失败!\n");
if (CryptSignHash(hHash,AT_SIGNATURE,NULL,0,NULL,dwSigLen))
printf("获取签名数据长度成功!\n");
else
printf("获取签名数据长度失败!\n");
if (*pSignature=(BYTE*)malloc(*dwSigLen))
printf("开辟签名数据长度的空间成功!\n");
else
printf("开辟签名数据长度的空间失败!\n");
if(CryptSignHash(hHash,AT_SIGNATURE,NULL,0,*pSignature,dwSigLen))
printf("签名成功!\n");
else
{
printf("签名失败!\n");
return FALSE;
}
if(hKey)
CryptDestroyKey(hKey);
if(hHash)
CryptDestroyHash(hHash);
if(hCryptProv)
CryptReleaseContext(hCryptProv, 0);
return TRUE;
}
BOOL verifSignature(CHAR *pData,DWORD dwDataLen,BYTE *pSignature,DWORD dwSigLen,BYTE *pPublicKey,DWORD dwPublicKeyLen)
{
HCRYPTPROV hCryptProv;
BOOL res=CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,0);
if(!res)
{
res=CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,CRYPT_NEWKEYSET);
if(!res)
{
printf("创建秘钥容器失败!\n");
}
}
HCRYPTKEY hPubKey;
if(CryptImportKey(hCryptProv,pPublicKey,dwPublicKeyLen,0,0,&hPubKey))
printf("导入公钥成功!\n");
else
printf("导入公钥失败!\n");
HCRYPTHASH hHash;
if(CryptCreateHash(hCryptProv,CALG_SHA1,0,0,&hHash))
printf("创建哈希对象成功!\n");
else
printf("创建哈希对象失败!\n");
if(CryptHashData(hHash,(const BYTE *)pData,dwDataLen,0))
printf("数据哈希完成!\n");
else
printf("数据哈希失败!\n");
if(CryptVerifySignature(hHash,pSignature,dwSigLen,hPubKey,NULL,0))
printf("验证签名成功!\n");
else
printf("验证签名失败!\n");
if(hHash)
CryptDestroyHash(hHash);
if(hCryptProv)
CryptReleaseContext(hCryptProv,0);
return TRUE;
}