注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出.
/*
*
*
* 文件名称:Signer.cpp
* 摘 要:
* 数字签名及验证
* 当前版本:1.0
* 作 者:周绍禹
* 创建日期:2012年3月4日
*/
#include "StdAfx.h"
#include "Signer.h"
#include "Map.h"
#include "generic.h"
#include "base64.h"
Signer::Signer():CSP_NAME(FEITIAN_CSP_NAME)
{
log = new Log("Signer");
certMsg = new CertMsg();
}
Signer::~Signer()
{
if(log) delete log;
if(certMsg) delete certMsg;
}
//-----------------------------------------------------------
// 函数名称:
// sign
// 参数:
// - string plain_text 明文
// - BYTE* target_SN_blob 目标证书的序列号字节数组
// - int cblob 目标证书的序列号字节数组大小
// 返回:
// Result*
// 说明:
// 通过指定的序列号查找证书以及私钥,对数据做数字签名操作
//-----------------------------------------------------------
Result* Signer::sign(string plain_text,BYTE* target_SN_blob,int cblob)
{
// 准备数据
HCRYPTPROV hProv;
if(!CryptAcquireContext(&hProv,
NULL,
CSP_NAME,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
{
DWORD dwLastErr = GetLastError();
if(NTE_BAD_KEYSET == dwLastErr)
{
Result* result = new Result("Signer.cpp",20,"密钥库不存在,或者访问被拒绝!","{}");
return result;
}
else{
if(!CryptAcquireContext(&hProv,
NULL,
this->CSP_NAME,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
Map* map = new Map(1);
map->put("errcode",dwLastErr);
string errcode = map->toString();
delete map;
Result* result = new Result("Signer.cpp",34,"密钥库已存在,创建密钥库失败!",errcode);
return result;
}
}
}
// 请求证书私钥服务
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;
DWORD dwKeyType = 0;
Result* result = certMsg->acquirePrivateKey(hProv,target_SN_blob,cblob,&hKeyProv,&dwKeyType);
if(!result->isSuccess())
{
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
log->error("Signer.cpp 86 acquirePrivateKey")->error(getErrorCode());
return result;
}
if(hKeyProv==NULL)
{
string errorcode = getErrorCode();
Result* result = new Result("Signer.cpp",57,"获取私钥服务失败!",errorcode.length()==0?"{}":errorcode);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
log->error("Signer.cpp 86 acquirePrivateKey")->error(errorcode);
return result;
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hKeyProv, // 容器句柄
CALG_MD5, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
string errorcode = getErrorCode();
Result* result = new Result("Singer.cpp",73,"创建HASH失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 102 CryptCreateHash")->error(errorcode);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
if(hKeyProv != NULL)
CryptReleaseContext(hKeyProv, 0);
return result;
}
BYTE *orgTextByte ;
int orgTextLen = plain_text.size();
orgTextByte = new BYTE[orgTextLen + 1];
for(int i=0;i<orgTextLen;i++){
orgTextByte[i]=plain_text[i];
}
orgTextByte[orgTextLen]='\0';
// 计算数据摘要
if(!CryptHashData(hHash, orgTextByte, orgTextLen, 0))
{
string errorcode = getErrorCode();
Result* result = new Result("Signer.cpp",94,"计算摘要失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 128 CryptHashData")->error(errorcode);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
if(hKeyProv != NULL)
CryptReleaseContext(hKeyProv, 0);
if(hHash)
CryptDestroyHash(hHash);
if(orgTextByte) delete[] orgTextByte;
return result;
}
DWORD cbSign = 4096;
BYTE *pbSign;
//获取签名数据摘要大小
if(!CryptSignHash(hHash, dwKeyType, NULL, 0, NULL, &cbSign))
{
string errorcode = getErrorCode();
Result* result = new Result("Signer.cpp",106,"获取签名大小失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 147 CryptSignHash")->error(errorcode);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
if(hKeyProv != NULL)
CryptReleaseContext(hKeyProv, 0);
if(hHash)
CryptDestroyHash(hHash);
if(orgTextByte) delete[] orgTextByte;
return result;
}
pbSign = new BYTE[cbSign];
//签名数据摘要
if(!CryptSignHash(hHash, dwKeyType, NULL, 0, pbSign, &cbSign))
{
string errorcode = getErrorCode();
Result* result = new Result("Signer.cpp",116,"签名失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 163 CryptSignHash")->error(errorcode);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
if(hKeyProv != NULL)
CryptReleaseContext(hKeyProv, 0);
if(hHash)
CryptDestroyHash(hHash);
if(orgTextByte) delete[] orgTextByte;
if(pbSign) delete[] pbSign;
return result;
}
//将签名值转成base64编码
string baseSign = Base64::base64_encode(pbSign,cbSign);
log->info("----------------------")->info("签名值:")->info(baseSign);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
if(hKeyProv != NULL)
CryptReleaseContext(hKeyProv, 0);
if(hHash)
CryptDestroyHash(hHash);
if(orgTextByte) delete[] orgTextByte;
if(pbSign) delete[] pbSign;
Result* sign_result = new Result(baseSign);
return sign_result;
}
//-----------------------------------------------------------
// 函数名称:
// verify
// 参数:
// - string signed_text_base64 签名值base64码
// - string cert_base64 数字证书base64码
// - string org_text 明文
// 返回:
// Result*
// 说明:
// 使用传入的证书base64码创建证书上下文,然后使用该证书及其公钥验证数字签名
//----------------------