CSP应用开发-签名和验签

#ifndef SIGNATURE_H
#define SIGNATURE_H

#include <windows.h>
#pragma warning(disable:4996)
/*********************************************************************************
* 函数名: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);
#endif
 #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)
{
    //1.获得一个CSP句柄
    HCRYPTPROV hCryptProv;
    BOOL res=CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,0);
    if(!res) //如果没有可用CSP
    {
        res=CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,CRYPT_NEWKEYSET); //创建秘钥容器
        if(!res)
        {
            printf("创建CSP容器失败!\n");
            return FALSE;
        }
    }

    //2.获取签名秘钥
    HCRYPTKEY hKey;
    res=CryptGetUserKey(hCryptProv,AT_SIGNATURE,&hKey);
    if(!res)    //没有可用的签名秘钥
    {
        res=CryptGenKey(hCryptProv,2,CRYPT_EXPORTABLE|0X04000000,&hKey); //创建一个ESA秘钥对
        if(!res)
        {
            printf("创建RSA秘钥对失败!\n");
            return FALSE;
        }
    }

    //3.导出公钥
    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");

    //4.对数据进行哈希签名
    //(1)创建hash对象,并将数据加到hash对象中
    HCRYPTHASH hHash;
    if(CryptCreateHash(hCryptProv,CALG_SHA1,0,0,&hHash))  //创建一个hash对象
        printf("创建哈希签名成功!\n");
    else
        printf("创建哈希签名失败!\n");
    if(CryptHashData(hHash,(const BYTE *)pData,dwDataLen,0)) //对一块数据进行哈希,把它加到指定的哈希对象中
        printf("将数据进行哈希成功!\n");
    else
        printf("将数据进行哈希失败!\n");

    //(2)获取签名长度
    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;
    }
    //5.释放空间
    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)
{
    //1.获得一个CSP句柄
    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");
        }
    }

    //2.导入公钥
    HCRYPTKEY hPubKey;
    if(CryptImportKey(hCryptProv,pPublicKey,dwPublicKeyLen,0,0,&hPubKey))
        printf("导入公钥成功!\n");
    else
        printf("导入公钥失败!\n");

    //3.计算哈希
    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");
    //4.验证哈希签名
    if(CryptVerifySignature(hHash,pSignature,dwSigLen,hPubKey,NULL,0))
        printf("验证签名成功!\n");
    else
        printf("验证签名失败!\n");
    //5.释放空间
    if(hHash)
    CryptDestroyHash(hHash);
    if(hCryptProv)
    CryptReleaseContext(hCryptProv,0);
    return TRUE;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

离水的鱼儿

一分也是爱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值