📄 evp.cpp
字号:
goto err;
}
pcert = X509_get_pubkey(x509);
if(pcert==NULL)
{
sprintf(OperMsg,"取得公钥密钥失败");
ret = FALSE;
goto err;
}
if (!(rsa = EVP_PKEY_get1_RSA(pcert)))
{
sprintf(OperMsg,"取得RSA密钥失败");
ret=FALSE;
goto err;
}
iblock_size = BN_num_bytes(rsa->n) - 11;//预加密长度,117
oblock_size = BN_num_bytes(rsa->n);//加密后长度,128
bufin = new unsigned char[iblock_size];
memset(bufin,0,iblock_size);
bufout = new unsigned char[oblock_size];
memset(bufout,0,oblock_size);
if(nInlen==0)//文件
{
for(;;)
{
inlen = fread(bufin,sizeof(char),iblock_size,infd);
if(!inlen)
break;
outlen = RSA_public_encrypt(inlen,bufin,bufout,rsa,RSA_PKCS1_PADDING);
if (outlen == -1)//加密后资料长度
{
sprintf(OperMsg,"RSA加密失败");
ret=FALSE;
goto err;
}
if(bOutType)
{
fwrite(bufout,sizeof(char),outlen,outfd);
memset(bufout,0,oblock_size);
}
else
{
uMaxMem -= outlen; //剩余缓冲大小
if(uMaxMem < 0)
{
strcpy(OperMsg, "输出缓冲过小,不能容纳操作结果");
ret = FALSE;
goto err;
}
memcpy(pOutStream + memtemplen, bufout, outlen);//拷贝到调用函数
memtemplen += outlen;
}
finishLen += inlen;
DrawProg(finishLen*HUNDRED/fileLen);
}
nOutlen = memtemplen;
}
else//内存区域
{
for(UINT i=0;;i++)
{
//每次 iblock_size 或实际长度
len = (nInlen>iblock_size)?iblock_size:nInlen;//内存区域长度
nInlen -= len;
outlen=RSA_public_encrypt(len,(UCHAR *)(pInStream+i*iblock_size),bufout,rsa,RSA_PKCS1_PADDING);
if (outlen == -1)//加密后资料长度
{
sprintf(OperMsg,"RSA加密失败");
ret = FALSE;
goto err;
}
if(bOutType)
{
fwrite(bufout,sizeof(char),outlen,outfd);
memset(bufout,0,outlen);
}
else
{
uMaxMem -= outlen; //剩余缓冲大小
if(uMaxMem < 0)
{
strcpy(OperMsg, "输出缓冲过小,不能容纳操作结果");
ret = FALSE;
goto err;
}
memcpy(pOutStream + memtemplen,bufout,outlen);//拷贝到调用函数
memtemplen += outlen;
}
finishLen += len;
DrawProg(finishLen*HUNDRED/fileLen);
if(nInlen <= 0) break;
}
nOutlen = memtemplen;
}
err:
if(infd!=NULL)
fclose(infd);
if(outfd!=NULL)
fclose(outfd);
if(pcert) EVP_PKEY_free(pcert);
if(x509) X509_free(x509);
if(rsa) RSA_free(rsa);
delete [] bufin;
delete [] bufout;
return ret;
}
//私钥解密
BOOL CEvp::RSAPrivDec(const BYTE * pKeyBuf/*[in]私钥*/,const UINT nKeyLen/*[in]私钥长度*/,
const char * pPwd/*[in]私钥密码*/,const BYTE * pInStream/*[in]输入文件或内存*/,
DWORD nInlen/*[in]数据长度,为0表示pInStream为文件名*/,BYTE * pOutStream/*[out]解密后的数据*/,
DWORD & nOutlen/*[in,out]in为0时候表示pOutStream为文件名,out解密后数据长度*/,
char * OperMsg/*[out]返回操作错误信息*/)
{
unsigned char * bufin = NULL,
* bufout = NULL;
UINT iblock_size = 0,
oblock_size = 0,
outlen = 0,
inlen = 0;
BOOL ret = true;
long fileLen = 0;//文件长度
long finishLen = 0;//完成长度
RSA * rsa = NULL;
EVP_PKEY * pkey = NULL;
FILE * outfd = NULL,
* infd = NULL;
int memtemplen = 0; //输出内存偏移
UINT len = 0; //输入内存剩余长度
int uMaxMem = nOutlen; //可能为负数,不能用UINT
BOOL bOutType = FALSE;//输出文件类型,内存-FALSE,文件-TRUE;
if(nOutlen == 0) bOutType = TRUE;
if(nInlen == 0)//输入为文件
{
if(pInStream == NULL || strlen((char*)pInStream)==0)
{
strcpy(OperMsg,"未指定输入文件");
return FALSE;
}
if ((infd = fopen ((char *)pInStream, "rb")) == NULL)//原文
{
sprintf(OperMsg,"打开文件%s失败",pInStream);
return FALSE;
}
fileLen = filelength(fileno(infd));//得到文件长度
}
else
fileLen = nInlen;
if(nOutlen == 0)//输出为文件
{
if(pOutStream == NULL || strlen((char*)pOutStream)==0)
{
strcpy(OperMsg,"未指定输出文件");
return FALSE;
}
if ((outfd = fopen ((char *)pOutStream, "wb")) == NULL)//原文
{
sprintf(OperMsg,"打开文件%s失败",pOutStream);
return FALSE;
}
}
pkey=CCertKey::LoadKey((char *)pKeyBuf,nKeyLen,(char *)pPwd,OperMsg);
if (pkey == NULL)
{
// sprintf(OperMsg,"取得私钥密钥失败");
ret=FALSE;
goto err;
}
if (!(rsa = EVP_PKEY_get1_RSA(pkey)))
{
sprintf(OperMsg,"取得RSA密钥失败");
ret=FALSE;
goto err;
}
iblock_size = BN_num_bytes(rsa->n);//预接密长度 128
oblock_size = BN_num_bytes(rsa->n) - 11;//杰密后长度 117
bufin=new unsigned char[iblock_size];
bufout=new unsigned char[oblock_size];
if(nInlen == 0)//文件
{
for(;;)
{
inlen=fread(bufin,sizeof(char),iblock_size,infd);
if(!inlen)
break;//117,128
outlen = RSA_private_decrypt(inlen,bufin,bufout,rsa,RSA_PKCS1_PADDING);
if (outlen == -1)//加密后资料长度
{
sprintf(OperMsg,"RSA解密失败");
ret=FALSE;
goto err;
}
if(bOutType)
{
fwrite(bufout,sizeof(char),outlen,outfd);
memset(bufout,0,oblock_size);
}
else
{
uMaxMem -= outlen; //剩余缓冲大小
if(uMaxMem < 0)
{
strcpy(OperMsg, "输出缓冲过小,不能容纳操作结果");
ret = FALSE;
goto err;
}
memcpy(pOutStream + memtemplen,bufout,outlen);//拷贝到调用函数
memtemplen += outlen;
}
finishLen+=inlen;
DrawProg(finishLen*HUNDRED/fileLen);
}
nOutlen = memtemplen;
}
else//内存
{
for(UINT i=0;;i++)
{
//每次 iblock_size 或实际长度
len = (nInlen>iblock_size)?iblock_size:nInlen;//内存区域长度
nInlen -= len;
outlen = RSA_private_decrypt(len,(UCHAR *)(pInStream+i*iblock_size),bufout,
rsa,RSA_PKCS1_PADDING);
if (outlen == -1)//加密后资料长度
{
sprintf(OperMsg,"RSA解密失败");
ret = FALSE;
goto err;
}
if(bOutType)
{
fwrite(bufout,sizeof(char),outlen,outfd);
memset(bufout,0,outlen);
}
else
{
uMaxMem -= outlen; //剩余缓冲大小
if(uMaxMem < 0)
{
strcpy(OperMsg, "输出缓冲过小,不能容纳操作结果");
ret = FALSE;
goto err;
}
memcpy(pOutStream + memtemplen,bufout,outlen);//拷贝到调用函数
memtemplen += outlen;
}
finishLen += len;
DrawProg(finishLen*HUNDRED/fileLen);
if(nInlen <= 0) break;
}
nOutlen = memtemplen;
}
err:
if(pkey) EVP_PKEY_free(pkey);
if(infd!=NULL)
fclose(infd);
if(outfd!=NULL)
fclose(outfd);
if(rsa) RSA_free(rsa);
delete [] bufin;
delete [] bufout;
return ret;
}
/*私钥加密(签名)*/
BOOL CEvp::RSAPrivEnc(const BYTE * pKeyBuf/*[in]私钥*/,const UINT nKeyLen/*[in]私钥长度*/,
const char * pPwd/*[in]私钥密码*/,const BYTE * pInStream/*[in]输入文件或内存*/,
DWORD nInlen/*[in]数据长度,为0表示pInStream为文件名*/,BYTE * pOutStream/*[out]加密后的数据*/,
DWORD & nOutlen/*[in,out]in为0时候表示pOutStream为文件名,out加密后数据长度*/,
char * OperMsg/*[out]返回操作错误信息*/)
{
RSA * rsa = NULL;
EVP_PKEY * pkey = NULL;
UINT iblock_size = 0,
oblock_size = 0,
outlen = 0,
inlen = 0;
BOOL ret = TRUE;
UCHAR * bufin = NULL,
* bufout = NULL;
long fileLen = 0;//文件长度
long finishLen = 0;//完成长度
int memtemplen = 0; //输出内存偏移
UINT len = 0; //输入内存剩余长度
int uMaxMem = nOutlen; //可能为负数,不能用UINT
FILE * outfd = NULL,
* infd = NULL;
BOOL bOutType = FALSE;//输出文件类型,内存-FALSE,文件-TRUE;
if(nOutlen == 0) bOutType = TRUE;
if(nInlen == 0)//输入为文件
{
if(pInStream == NULL || strlen((char*)pInStream)==0)
{
strcpy(OperMsg,"未指定输入文件");
return FALSE;
}
if ((infd = fopen ((char *)pInStream, "rb")) == NULL)//原文
{
sprintf(OperMsg,"打开文件%s失败",pInStream);
return FALSE;
}
fileLen = filelength(fileno(infd));//得到文件长度
}
else
fileLen = nInlen;
if(nOutlen == 0)//输出为文件
{
if(pOutStream == NULL || strlen((char*)pOutStream)==0)
{
strcpy(OperMsg,"未指定输出文件");
return FALSE;
}
if ((outfd = fopen ((char *)pOutStream, "wb")) == NULL)//原文
{
sprintf(OperMsg,"打开文件%s失败",pOutStream);
return FALSE;
}
}
pkey=CCertKey::LoadKey((char *)pKeyBuf,nKeyLen,(char *)pPwd,OperMsg);
if (pkey == NULL)
{
// sprintf(OperMsg,"取得私钥密钥失败");
ret=FALSE;
goto err;
}
if (!(rsa = EVP_PKEY_get1_RSA(pkey)))
{
sprintf(OperMsg,"取得RSA密钥失败");
ret=FALSE;
goto err;
}
iblock_size = BN_num_bytes(rsa->n) - 11;//输入长度 117
oblock_size = BN_num_bytes(rsa->n);//加密后长度 128
bufin=new unsigned char[iblock_size];
bufout=new unsigned char[oblock_size];
if(nInlen == 0)//文件
{
for(;;)
{
inlen=fread(bufin,sizeof(char),iblock_size,infd);
if(!inlen)
break;//117,128
outlen = RSA_private_encrypt(inlen,bufin,bufout,rsa,RSA_PKCS1_PADDING);
if (outlen == -1)//加密后资料长度
{
sprintf(OperMsg,"RSA加密失败");
ret=FALSE;
goto err;
}
if(bOutType)
{
fwrite(bufout,sizeof(char),outlen,outfd);
memset(bufout,0,oblock_size);
}
else
{
uMaxMem -= outlen; //剩余缓冲大小
if(uMaxMem < 0)
{
strcpy(OperMsg, "输出缓冲过小,不能容纳操作结果");
ret = FALSE;
goto err;
}
memcpy(pOutStream + memtemplen,bufout,outlen);//拷贝到调用函数
memtemplen += outlen;
}
finishLen+=inlen;
DrawProg(finishLen*HUNDRED/fileLen);
}
nOutlen = memtemplen;
}
else//内存
{
for(UINT i=0;;i++)
{
//每次 iblock_size 或实际长度
len = (nInlen>iblock_size)?iblock_size:nInlen;//内存区域长度
nInlen -= len;
outlen = RSA_private_encrypt(len,(UCHAR *)(pInStream+i*iblock_size),
bufout,rsa,RSA_PKCS1_PADDING);
if (outlen == -1)//加密后资料长度
{
sprintf(OperMsg,"RSA加密失败");
ret = FALSE;
goto err;
}
if(bOutType)
{
fwrite(bufout,sizeof(char),outlen,outfd);
memset(bufout,0,outlen);
}
else
{
uMaxMem -= outlen; //剩余缓冲大小
if(uMaxMem < 0)
{
strcpy(OperMsg, "输出缓冲过小,不能容纳操作结果");
ret = FALSE;
goto err;
}
memcpy(pOutStream + memtemplen,bufout,outlen);//拷贝到调用函数
memtemplen += outlen;
}
finishLen += len;
DrawProg(finishLen*HUNDRED/fileLen);
if(nInlen <= 0) break;
}
nOutlen = memtemplen;
}
err:
if(pkey) EVP_PKEY_free(pkey);
if(infd!=NULL)
fclose(infd);
if(outfd!=NULL)
fclose(outfd);
if(rsa) RSA_free(rsa);
delete [] bufin;
delete [] bufout;
return ret;
}
//公钥解密
BOOL CEvp::RSAPubDec(const BYTE * pCertBuf/*[in]公钥*/,const UINT nCertLen/*[in]公钥长度*/,
const char * pPwd/*[in]公钥密码,只针对PFX包文件*/,const BYTE * pInStream/*[in]输入文件或内存*/,
DWORD nInlen/*[in]数据长度,为0表示pInStream为文件名*/,BYTE * pOutStream/*[out]加密后的数据*/,
DWORD & nOutlen/*[in,out]in为0时候表示pOutStream为文件名,out加密后数据长度*/,
char * OperMsg/*[out]返回操作错误信息*/)
{
UINT iblock_size = 0, //输入块长度
oblock_size = 0; //输出块长度
unsigned char * bufin=NULL,
* bufout=NULL;
int inlen = 0,
outlen = 0;
BOOL ret = TRUE;
long fileLen = 0;//文件长度
long finishLen = 0;//完成长度
X509 * x509 = NULL;
EVP_PKEY * pcert = NULL;
RSA * rsa = NULL;
int memtemplen = 0; //输出内存偏移
UINT len = 0; //输入内存剩余长度
int uMaxMem = nOutlen; //可能为负数,不能用UINT
BOOL bOutType = FALSE;//输出文件类型,内存-FALSE,文件-TRUE;
if(nOutlen == 0) bOutType = TRUE;
FILE * outfd = NULL,
* infd = NULL;
if(nInlen == 0)//输入为文件
{
if(pInStream == NULL || strlen((char*)pInStream)==0)
{
strcpy(OperMsg,"未指定输入文件");
return FALSE;
}
if ((infd = fopen ((char *)pInStream, "rb")) == NULL)//原文
{
sprintf(OperMsg,"打开文件%s失败",pInStream);
return FALSE;
}
fileLen = filelength(fileno(infd));//得到文件长度
}
else
fileLen = nInlen;
if(nOutlen == 0)//输出为文件
{
if(pOutStream == NULL || strlen((char*)pOutStream)==0)
{
strcpy(OperMsg,"未指定输出文件");
return FALSE;
}
if ((outfd = fopen ((char *)pOutStream, "wb")) == NULL)//原文
{
sprintf(OperMsg,"打开文件%s失败",pOutStream);
return FALSE;
}
}
x509 = CCertKey::LoadCert((char *)pCertBuf,nCertLen,(char *)pPwd,OperMsg);
if (x509 == NULL)
{
ret = FALSE;
goto err;
}
pcert = X509_get_pubkey(x509);
if(pcert==NULL)
{
sprintf(OperMsg,"取得公钥密钥失败");
ret = FALSE;
goto err;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -