最近在做C++下的一些加密和解密的相关项目,整理了一下使用Openssl对于证书的一些操作,其中很多都是在网上搜索到的。准备在这个项目结束之后写一些关于Openssl使用上的心得。
获取的公私钥的代码:
BOOL CTesteclibDlg::ParseDB(char *strP12, char *strPwd)
{
EVP_PKEY *key=NULL;
X509 *cert=NULL;
BIO * bio=NULL;
STACK_OF(X509) *ca = NULL;
PKCS12 *p12=NULL;
if((bio=BIO_new_file(strP12, "r")) == NULL)
{
MessageBox("打开文件错误!","EKEY提示",MB_OK);
return false;
}
SSLeay_add_all_algorithms();
p12 = d2i_PKCS12_bio(bio, NULL);
if (!PKCS12_parse(p12, strPwd, &key, &cert, &ca))
{
MessageBox("解析证书包文件错误!","EKEY提示",MB_OK);
return false;
}
BYTE *pubbuf;
BYTE *pribuf;
dwPubKeyLen=i2d_PublicKey(key,NULL);//得到公钥的长度
pbPubKey = (BYTE *)LocalAlloc(LMEM_ZEROINIT, dwPubKeyLen);
pubbuf = pbPubKey;
i2d_PublicKey(key,&pubbuf);//PublicKey DER code
dwPriKeyLen=i2d_PrivateKey(key,NULL);//得到私钥的长度
pbPriKey = (BYTE *)LocalAlloc(LMEM_ZEROINIT, dwPriKeyLen);
pribuf = pbPriKey;
i2d_PrivateKey(key,&pribuf);//PrivateKey DER code
PKCS12_free(p12);
X509_free(cert);
EVP_PKEY_free(key);
//EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
return true;
}
下面这个也是:
/*----------------------------------------------------------------------------*/
// 函数名称: ParsePkcs12
// 功能描叙: 解析pkcs12证书格式
// 输入参数:
// const string &strP12 pkc12文件
// 输出参数:
// X509 **pX509 X509证书
// EVP_PKEY **pKey 私钥
// 返回值:
// bool 成功 true;失败 false;
/*----------------------------------------------------------------------------*/
bool ParsePkcs12( const string &strP12, const string &strPwd,
X509 **pX509, EVP_PKEY **pKey )
{
bool bState = false;
STACK_OF( X509 ) * pCA = NULL;
BIO * bio = NULL;
PKCS12 * p12 = NULL;
#if 0
//输入为磁盘文件
if ( ( bio = BIO_new_file( strP12.c_str(), "r" ) ) == NULL )
{
cout << "BIO_new_file create BIO using " << strP12 << " failure!" << endl;
goto end;
}
#else
//输入为内存文件
char *pBuff = NULL, *pOffset = NULL;;
int cSize = 0, cReaded = 0, cOffset = 0;
FILE *fp = NULL;
cSize = GetFileSize( strP12 );
if ( cSize < 0 )
{
cout << "Get " << strP12 << "'s size failure!" << endl;
goto end;
}
pBuff = new char[ cSize ];
memset( pBuff, 0x0, cSize );
fp = fopen( strP12.c_str(), "rb" );
if ( NULL == fp )
{
cout << "open " << strP12 << " failure!" << endl;
goto end;
}
pOffset = pBuff ;
cOffset = cSize ;
cReaded = fread( pOffset, 1, cOffset, fp );
while ( cReaded < cSize )
{
pOffset += cReaded;
cOffset -= cReaded;
};
fclose( fp );
if ( NULL == ( bio = BIO_new_mem_buf( pBuff, cSize ) ) )
{
cout << "BIO_new_mem_buf creates a memory BIO using " << cSize << "bytes failure!" << endl;
goto end;
}
#endif
SSLeay_add_all_algorithms();
p12 = d2i_PKCS12_bio( bio, NULL );
if ( NULL == p12 )
{
cout << "d2i_PKCS12_bio failure!" << endl;
goto end;
}
if ( !PKCS12_parse( p12, strPwd.c_str(), pKey, pX509 /*PEM*/, &pCA ) )
{
cout << "PKCS12_parse failure!" << endl;
goto end;
}
bState = true;
end:
PKCS12_free( p12 );
if ( bio != NULL )
{
BIO_free( bio );
bio = NULL;
}
if ( pBuff )
{
delete [] pBuff;
pBuff = NULL;
}
return bState;
}
int CCAOperate::DoSplitP12(char *szP12FileName,
char *szPwd,
char *szCertFileName,
char *szPrivateKeyFileName,
char *szPrivateKeyPwd)
{
EVP_PKEY *pkey;
X509 *cert;
STACK_OF(X509) *ca = NULL;
PKCS12 *p12;
BIO *in = NULL;
BIO *inclcert = NULL;
BIO *inpvk = NULL;
in = BIO_new_file(szP12FileName, "rb");
if (!in)
{
m_str.Format("%s","open p12 file fail");
goto err;
}
p12 = d2i_PKCS12_bio (in, NULL);
if (!p12)
{
m_str.Format("%s","Error reading PKCS#12 file");
goto err;
}
if (!PKCS12_parse(p12, szPwd, &pkey, &cert, &ca))
{
m_str.Format("%s", "Error parsing PKCS#12 file");
goto err;
}
inpvk = BIO_new_file(szPrivateKeyFileName, "w");
if (!inpvk)
{
m_str.Format("Error opening file %s", szPrivateKeyFileName);
goto err;
}
if (pkey)
{
if(szPrivateKeyPwd)
{
int len =strlen(szPrivateKeyPwd);
PEM_write_bio_PrivateKey(inpvk, pkey, EVP_des_ede3_cbc(),
(unsigned char*)szPrivateKeyFileName,len, NULL, NULL);
}
else
PEM_write_bio_PrivateKey(inpvk, pkey, NULL,NULL,0, NULL, NULL);
}
inclcert = BIO_new_file(szCertFileName, "w");
if (!szCertFileName)
{
m_str.Format("Error opening file %s", szCertFileName);
goto err;
}
if (cert)
{
PEM_write_bio_X509(inclcert, cert);
}
// free memory
if(in) BIO_free(in);
if(inpvk) BIO_free(inpvk);
if(inclcert)BIO_free(inclcert);
if(p12) PKCS12_free(p12);
if(pkey) EVP_PKEY_free(pkey);
if(cert) X509_free(cert);
return 1;
err:
if(in) BIO_free(in);
if(inpvk) BIO_free(inpvk);
if(inclcert)BIO_free(inclcert);
if(p12) PKCS12_free(p12);
if(pkey) EVP_PKEY_free(pkey);
if(cert) X509_free(cert);
return -1;
}