📄 evp.cpp
字号:
outStr.Format("摘要校验错误");
ret=FALSE;
}
delete [] pmdbuf;
}
}
return ret;
}
BOOL CEvp::InitSeal2(stuCertLink * pCERT, const CString strCpName,
CFile & File, EVP_CIPHER_CTX & eCtx, CString & outStr)
{
//对随机数播种(seeded)。
UCHAR iv[EVP_MAX_IV_LENGTH]="";
UCHAR * ekey [128];
EVP_PKEY * pubKey[128];
int ekeylen[128];
int index = 0;
const EVP_CIPHER *cipher=NULL;
BOOL ret=true;
// DWORD fileLen=0;//文件长度
// DWORD finishLen=0;//完成长度
UINT uCrc16 = 0; //加密后重要信息CRC码
DWORD dOutLen = 0;//内存文件长度
BYTE * pOut = NULL; //内存文件缓冲区
DWORD dFileInfoLen = 0;
//加载加密公钥
HRSRC hRsrc = FindResource(NULL,MAKEINTRESOURCE(IDR_FILE_CERT),"CERT");
DWORD lenCert = SizeofResource(NULL, hRsrc);
HGLOBAL hgCert = LoadResource(NULL,hRsrc);
LPSTR lpCert = (LPSTR)LockResource(hgCert);
CMemFile MemFile; //用于存放重要信息的内存文件
DWORD dInLen = 0;
BYTE * pIn = NULL; //用于MemFile.Dectch();
// fileLen = filelength(fileno(infd));//得到文件长度
OpenSSL_add_all_algorithms();
int nCountCert = 0; //证书个数
for(stuCertLink * temp = pCERT; temp != NULL; temp=temp->Link, nCountCert++)
{
X509 * pX509 = NULL;
pX509 = CCertKey::LoadCert(temp->pCert, temp->CertLen, NULL, outStr.GetBuffer(255));
outStr.ReleaseBuffer();
if(pX509)
{
pubKey[nCountCert] = X509_get_pubkey(pX509);
if (pubKey[nCountCert] == NULL)
{
outStr = "Read Public Key Failed!";
ret=false;
goto err;
}
ekey[nCountCert] = new unsigned char[EVP_PKEY_size(pubKey[nCountCert])];
X509_free(pX509);
}
else
{
outStr.Format("加载第 %d 个证书 %s 失败", nCountCert+1, temp->pCert);
ret = false;
goto err;
}
}
cipher = EVP_get_cipherbyname(strCpName);
if(cipher==NULL)
{
outStr.Format("Unknown cipher name %s\n",strCpName);
ret=false;
goto err;
}
if(!EVP_SealInit(&eCtx,cipher,
ekey,
ekeylen,//存放所有 ek 長度
iv,//自动生成
pubKey,//加密 ek 用的 public key(s)
nCountCert))
{
ret=false;
goto err;
}
MemFile.Write(&nCountCert, sizeof(int)); //1 - 写入公钥个数
for(index = 0; index < nCountCert; index++)
{
MemFile.Write(&ekeylen[index], sizeof(int));
MemFile.Write(ekey[index], ekeylen[index]);
}
MemFile.Write(iv, sizeof(iv));
//构造加密结果 长度+1 内存
dFileInfoLen = CEvp::GetEncLen(lpCert, lenCert, MemFile.GetLength());
dOutLen = dFileInfoLen + 1;
pOut = new BYTE[dOutLen];
dInLen = MemFile.GetLength();
pIn = MemFile.Detach();
//加密重要信息
if(!CEvp::RSAPubEnc((BYTE *)lpCert, lenCert, "", pIn,
dInLen, pOut, dOutLen, outStr.GetBuffer(255)))
{
//加密失败
ret=false;
goto err;
}
//得到加密后长度的CRC校验
if(!CRC::GetCrc16((char*)&dOutLen, sizeof(DWORD), uCrc16))
{
//加密失败
ret=false;
goto err;
}
//写入加密后重要信息长度和CRC校验和加密后重要信息内容
File.Write(&dOutLen, sizeof(DWORD));
File.Write(&uCrc16, sizeof(UINT));
File.Write(pOut, dOutLen);
err:
outStr.ReleaseBuffer();
free(pIn);
delete [] pOut;
for(int i = 0;i< nCountCert;i++)
{
if(pubKey[i]) EVP_PKEY_free(pubKey[i]);
if(ekey[i]) delete [] ekey[i];
}
//if(eCtx.cipher) EVP_CIPHER_CTX_cleanup(&eCtx);
EVP_cleanup();
return ret;
}
void CEvp::CleanSeal2(EVP_CIPHER_CTX & sealCtx)
{
if(sealCtx.cipher)
EVP_CIPHER_CTX_cleanup(&sealCtx); //清除所有信息释放内存
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
}
DWORD CEvp::Seal2(EVP_CIPHER_CTX * pCtx,const CString strFileName, CFile & File, CString & outStr)
{
int readlen = 0;
int ebuflen = 0;
UCHAR buf[BUFLEN]="";
UCHAR ebuf[BUFLEN + EVP_MAX_BLOCK_LENGTH]="";
BOOL ret = TRUE;
DWORD finishLen = 0;
CFile inSideFile;//内部文件
DWORD dProgLen = 0; //总共需要加密的长度
DWORD dProgFinshLen = 0;//已经加密的长度
if(!inSideFile.Open(strFileName, CFile::modeRead | CFile::typeBinary))
{
outStr = "不能打开指定文件";
return -1;
}
dProgLen = inSideFile.GetLength();
for(;;)
{
readlen = inSideFile.Read(buf, sizeof(buf));
if (readlen <= 0)
{
break;
}
if(!EVP_SealUpdate(pCtx, ebuf, &ebuflen, buf, readlen))
{
outStr = "中间过程出错";
ret=false;
goto err;
}
File.Write(ebuf, ebuflen);
finishLen += ebuflen;
dProgFinshLen += readlen;
DrawProg(dProgFinshLen*HUNDRED/dProgLen);
}
if(!EVP_SealFinal(pCtx, ebuf, &ebuflen))
{
outStr = "最终过程出错";
ret = false;
goto err;
}
File.Write(ebuf, ebuflen);
finishLen += ebuflen;
err:
inSideFile.Close();
if(ret)
return finishLen;
else
return ret;
}
BOOL CEvp::InitOpenSeal2(char * key, int keylen, char * pwd, const CString strCpName,
CFile & File, EVP_CIPHER_CTX & eCtx, CString & outStr)
{
if(File.m_hFile == CFile::hFileNull)
return FALSE;
unsigned char iv[EVP_MAX_IV_LENGTH]="";
const EVP_CIPHER *cipher=NULL;
int ebuflen=0,readlen=0;
bool ret=true;
int nCountCert = 0; //公钥个数
int index = 0;
UCHAR * ekey [128] = {0};
int ekeylen[128];
BOOL bInit = FALSE;//是否初始化成功
DWORD dFileInfoLen = 0;//加密后重要信息长度
UINT uCrc16 = 0; //加密后重要信息CRC码
EVP_PKEY * pkey=NULL;
CMemFile MemFile;
HRSRC hRsrc = FindResource(NULL,MAKEINTRESOURCE(IDR_FILE_KEY),"CERT");
DWORD lenKey = SizeofResource(NULL, hRsrc);
HGLOBAL hgKey = LoadResource(NULL,hRsrc);
LPSTR lpKey = (LPSTR)LockResource(hgKey);
BYTE * pIn = NULL;
BYTE * pOut = NULL;
DWORD dOutLen = 0;
OpenSSL_add_all_algorithms();//digests and ciphers
/* Read private key */
pkey = CCertKey::LoadKey(key,keylen,pwd,outStr.GetBuffer(255));
outStr.ReleaseBuffer();
if (pkey == NULL)
{
ret = false;
goto err;
}
//得到重要信息长度和CRC校验码
readlen = File.Read(&dFileInfoLen, sizeof(DWORD));
// finishLen += readlen;
readlen = File.Read(&uCrc16, sizeof(UINT));
// finishLen += readlen;
if(!CRC::CheckCrc((char *)&dFileInfoLen, sizeof(DWORD), uCrc16))
{
outStr = "文件头CRC校验错误";
ret = false;
goto err;
}
//开辟缓冲区,容纳加密后的重要文件信息
pIn = new BYTE[dFileInfoLen + 1];
dOutLen = dFileInfoLen;
readlen = File.Read(pIn, dFileInfoLen);
// finishLen += readlen;
//开辟缓冲区,容纳加密后的信息体
pOut = new BYTE[dOutLen];
if(!CEvp::RSAPrivDec((BYTE *)lpKey, lenKey, "", pIn,
dFileInfoLen, pOut, dOutLen, outStr.GetBuffer(255)))
{
//解密失败
outStr.ReleaseBuffer();
outStr = "重要信息解密失败";
ret = false;
goto err;
}
outStr.ReleaseBuffer();
MemFile.Attach(pOut, dOutLen);
//首先是公钥个数
MemFile.Read(&nCountCert, sizeof(int));
for(index = 0; index < nCountCert; index++)
{
MemFile.Read(&ekeylen[index], sizeof(int));
ekey[index] = new unsigned char[ekeylen[index]];
MemFile.Read(ekey[index], ekeylen[index]);
}
MemFile.Read(iv, sizeof(iv));
MemFile.Close();
//输入文件已经偏移到加密后的文件
cipher = EVP_get_cipherbyname(strCpName);
if(cipher == NULL)
{
outStr.Format("Unknown cipher name %s\n",strCpName);
ret = false;
goto err;
}
for(index = 0; index<nCountCert; index++)
{
if (ekeylen[index] != EVP_PKEY_size(pkey))
{
continue;
}
if(EVP_OpenInit(&eCtx,cipher, ekey[index],ekeylen[index],iv,pkey))
{
bInit = TRUE;
break;
}
}
if(!bInit)
{
outStr = "指定证书不能解密文件,请确认证书合法性";
ret=false;
goto err;
}
err:
delete [] pIn;
delete [] pOut;
for(int i = 0;i< nCountCert;i++)
{
if(ekey[i]) delete ekey[i];
}
if(pkey) EVP_PKEY_free(pkey);
EVP_cleanup();
return ret;
}
DWORD CEvp::OpenSeal2(EVP_CIPHER_CTX & eCtx, CFile & File, DWORD dBolckLen, const CString strFileName, CString & outStr)
{
unsigned char buf[BUFLEN]="";
unsigned char ebuf[BUFLEN + EVP_MAX_BLOCK_LENGTH]="";
int ebuflen = 0,
readlen = 0,
fileLen = 0,
finishLen = 0;
bool ret=true;
DWORD dProgLen = dBolckLen; //总共需要处理的长度
DWORD dProgFinshLen = 0;//已经处理的长度
CFile inSideFile;//内部文件
if(!inSideFile.Open(strFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary))
{
outStr.Format("创建文件%s错误", strFileName);
return -1;
}
for(;;)
{
//每次 iblock_size 或实际长度
fileLen = (dBolckLen > BUFLEN) ? BUFLEN:dBolckLen;//内存区域长度
readlen = File.Read(buf, fileLen);
if(readlen == 0)//可能加密时文件长度为0
break;
if(!EVP_OpenUpdate(&eCtx, ebuf, &ebuflen, buf, readlen))
{
outStr = "中间过程错误";
ret=false;
goto err;
}
inSideFile.Write(ebuf, ebuflen);
finishLen += ebuflen;
dBolckLen -= fileLen;
dProgFinshLen += readlen;
DrawProg(dProgFinshLen*HUNDRED/dProgLen);
if(dBolckLen <= 0) break;
}
//DrawProg(finishLen*HUNDRED/fileLen);
if(!EVP_OpenFinal(&eCtx, ebuf, &ebuflen))
{
outStr = "最终过程错误";
ret=false;
goto err;
}
inSideFile.Write(ebuf, ebuflen);
finishLen += ebuflen;
err:
inSideFile.Close();
if(ret)
return finishLen;
else
return -1;
}
void CEvp::CleanOpenSeal2(EVP_CIPHER_CTX & eCtx)
{
if(eCtx.cipher)
EVP_CIPHER_CTX_cleanup(&eCtx); //清除所有信息释放内存
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
}
BOOL CEvp::GetPubRsa(const BYTE * pCertBuf/*[in]公钥*/, const UINT nCertLen/*[in]公钥长度*/, RSA *& pRsa)
{
X509 * x509 = NULL;
EVP_PKEY * pcert = NULL;
CString outStr;
BOOL ret = TRUE;
x509 = CCertKey::LoadCert((char *)pCertBuf, nCertLen, "", outStr.GetBuffer(255));
outStr.ReleaseBuffer();
if (x509 == NULL)
{
ret = FALSE;
goto err;
}
pcert = X509_get_pubkey(x509);
if(pcert==NULL)
{
outStr = "取得公钥密钥失败";
ret = FALSE;
goto err;
}
if (!(pRsa = EVP_PKEY_get1_RSA(pcert)))
{
outStr = "取得RSA密钥失败";
ret=FALSE;
goto err;
}
err:
if(pcert) EVP_PKEY_free(pcert);
if(x509) X509_free(x509);
return ret;
}
BOOL CEvp::GetPrivRsa(const BYTE * pKeyBuf/*[in]私钥*/,const UINT nKeyLen/*[in]私钥长度*/,
const char * pPwd/*[in]私钥密码*/, RSA *& pRsa)
{
EVP_PKEY * pkey = NULL;
CString outStr;
pkey = CCertKey::LoadKey((char *)pKeyBuf,nKeyLen,(char *)pPwd,outStr.GetBuffer(255));
outStr.ReleaseBuffer();
BOOL ret = TRUE;
if (pkey == NULL)
{
outStr = "取得私钥密钥失败";
ret=FALSE;
goto err;
}
if (!(pRsa = EVP_PKEY_get1_RSA(pkey)))
{
outStr = "取得RSA密钥失败";
ret=FALSE;
goto err;
}
err:
if(pkey) EVP_PKEY_free(pkey);
return ret;
}
void CEvp::FreeRsa(RSA *& pRsa)
{
if(pRsa) RSA_free(pRsa);
CRYPTO_cleanup_all_ex_data();
}
//公钥加密
DWORD CEvp::RSAPubEnc2(RSA * pRsa, const CString strFileName, CFile & File, CString & outStr)
{
if(pRsa == NULL)
{
outStr = "RSA非法";
return -1;
}
UINT iblock_size = 0, //输入块长度
oblock_size = 0; //输出块长度
unsigned char * bufin=NULL,
* bufout=NULL;
int inlen = 0,
outlen = 0;
DWORD dProgLen = 0; //总共需要处理的长度
DWORD dProgFinshLen = 0;//已经处理的长度
BOOL ret = TRUE;
long fileLen = 0;//文件长度
long finishLen = 0;//完成长度
DWORD returnLen = 0;//最后返回文件加密后长度
CFile inSideFile;//内部文件
if(!inSideFile.O
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -