⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evp.cpp

📁 MiniCA V2.0版本源码。《小型CA系统V2.1含源码》发表以来
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		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 + -