孙本新到底是不是医生:OpenSSL RSA 加密、解密

来源:百度文库 编辑:中财网 时间:2024/05/04 16:52:31
#include
#include
#include #pragma comment(lib, "libeay32.lib") #define MAX_LENGTH 1024
//////////////////////////////////////////////////////////////////////////
// 产生RSA公钥和密钥,并保存在文件中
//////////////////////////////////////////////////////////////////////////
BOOL GenerateRSAKey()
{
 RSA *rsa=NULL;
 TRACE(_T("正在产生RSA密钥...\n"));
 rsa = RSA_generate_key(MAX_LENGTH, RSA_F4, NULL, NULL);
 if (NULL == rsa)
 {
  TRACE(_T("gen rsa error\n"));
  return FALSE;
 }

 // 公钥
 BIO *bp = BIO_new(BIO_s_file());
 if (0 >= BIO_write_filename(bp, "public.pem"))
 {
  TRACE(_T("write error\n"));
  return FALSE;
 }

 if (1 != PEM_write_bio_RSAPublicKey(bp, rsa))
 {
  TRACE(_T("write public key error\n"));
  return FALSE;
 } 
 TRACE(_T("保存公钥成功\n"));
 BIO_free_all(bp);

 char passwd[]="1234";
 // 私钥
 // bp = BIO_new_file("private.pem", "w");
 bp = BIO_new(BIO_s_file());
 if ( 0 >= BIO_write_filename(bp, "private.pem"))
 {
  TRACE(_T("write error\n"));
  return FALSE;
 }

 if ( 1 != PEM_write_bio_RSAPrivateKey(bp, rsa, NULL/*EVP_des_ede3()*/, NULL/*(unsigned char*)passwd*/, 0/*5*/, NULL, NULL))
 {
  TRACE(_T("write private key error\n"));
  return FALSE;
 }
 TRACE(_T("保存私钥成功\n"));
 BIO_free_all(bp);
 RSA_free(rsa);

 return TRUE;
}

//////////////////////////////////////////////////////////////////////////
// 私钥完成加密
//////////////////////////////////////////////////////////////////////////
BOOL EncryptByPrivateKey(CString strFrom, int nFromLen, CString& strTo, int& nOutLen)
{
 BOOL bRet = FALSE;

 BIO *pBio = NULL;
 pBio = BIO_new_file("private.pem", "r");
 if (NULL == pBio)
 {
  return bRet;
 }

 RSA *pRsa = PEM_read_bio_RSAPrivateKey(pBio, NULL, NULL, NULL);
 BIO_free_all(pBio);
 if (NULL == pRsa)
 {
  return bRet;
 }

 char *pFrom = NULL;
 pFrom = (char*)malloc(MAX_LENGTH);
 ASSERT(NULL != pFrom);
 memset(pFrom, 0, MAX_LENGTH);
 WideCharToMultiByte(CP_ACP, 0, strFrom, -1, pFrom, MAX_LENGTH, NULL, NULL);

 unsigned char * pTo = NULL;
 pTo = (unsigned char *)malloc(sizeof(unsigned char)*MAX_LENGTH);
 ASSERT(NULL != pTo);
 memset(pTo, 0, MAX_LENGTH);

 nOutLen = RSA_private_encrypt((RSA_size(pRsa)-11) > nFromLen ? nFromLen : RSA_size(pRsa)-11,
  reinterpret_cast(pFrom),
  pTo,
  pRsa,
  RSA_PKCS1_PADDING);

 strFrom.ReleaseBuffer();

 unsigned char *pEncodeStr = (unsigned char *)malloc(MAX_LENGTH/*(nOutLen-1)/3 * 4 + 4*/);
 memset(pEncodeStr, 0, MAX_LENGTH);
 int nEncodeLen = ::EncodeBase64(pTo, pEncodeStr, nOutLen);
 if (-1 == nEncodeLen) // 编码失败
 {
  free(pFrom);
  free(pEncodeStr);
  return bRet;
 }
 strTo = pEncodeStr;

 free(pFrom);
 free(pTo);
 free(pEncodeStr);
 RSA_free(pRsa);

 if (nOutLen >= 0)
 {
  bRet = TRUE;
 }

 return bRet;
}

//////////////////////////////////////////////////////////////////////////
// 公钥完成解密
//////////////////////////////////////////////////////////////////////////
BOOL DecryptByPublicKey(CString strFrom, int nFromLen, CString& strTo, int& nOutLen)
{
 BOOL bRet = FALSE;

 BIO *pBio = BIO_new_file("public.pem", "r");
 if (NULL == pBio)
 {
  return bRet;
 }

 RSA *pRsa = PEM_read_bio_RSAPublicKey(pBio, NULL, NULL, NULL);
 BIO_free_all(pBio);
 if (NULL == pRsa)
 {
  return bRet;
 }

 CString strTemp;
 char *pFrom = NULL;
 pFrom = (char*)malloc(MAX_LENGTH);
 ASSERT(NULL != pFrom);
 memset(pFrom, 0, MAX_LENGTH);

 WideCharToMultiByte(CP_ACP, 0, strFrom, -1, pFrom, MAX_LENGTH, NULL, NULL);
 int nlen = strlen(pFrom)/sizeof(unsigned char);
 int nDeleteLen = 0;
 strTemp = pFrom;
 while(pFrom[--nlen] == '=')
 {
  nDeleteLen++;
 }

 unsigned char* pDecode = NULL;
 pDecode = (unsigned char*)malloc(MAX_LENGTH);
 memset(pDecode, 0, MAX_LENGTH);
 int nDecodeLen = ::DecodeBase64(reinterpret_cast(pFrom), pDecode, strFrom.GetLength());
 if (-1 == nDecodeLen) // 解码错误
 {
  free(pFrom);
  free(pDecode);
  return bRet;
 }

 unsigned char * pTo = NULL;
 pTo = (unsigned char *)malloc(MAX_LENGTH);
 ASSERT(NULL != pTo);
 memset(pTo, 0, MAX_LENGTH);

 nOutLen = RSA_public_decrypt(
  (nDecodeLen-nDeleteLen),
  pDecode,
  pTo,
  pRsa,
  RSA_PKCS1_PADDING);

 strFrom.ReleaseBuffer();
 strTo = pTo;

 free(pFrom);
 free(pDecode);
 free(pTo);
 RSA_free(pRsa);

 if(nOutLen >= 0)
 {
  bRet = TRUE;
 }

 return bRet;
}