Openssl证书的读取和分离

最近在做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;
}


分离p12证书为公钥证书与私钥:

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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值