万捷博客

万捷博客
一个知识汇聚的地方
首页 » c++ » c++使用openssl实现rsa加密解密【windows版】

c++使用openssl实现rsa加密解密【windows版】

 

windows中使用c++通过openssl实现rsa加密的文章非常多,但是真正能用的没有几个,大部分都是linux版本的,而且代码不全、版本老旧、有BUG无法调试等,今天给大家带来一个完全可以的示例,希望对大家有所帮助。

效果图

c++通过openssl实现rsa加密解密

main.cpp文件

/*
    测试openssl版本为:Win32OpenSSL-1_1_0i

    调试本源码前,必须先安装openssl

    并且,将openssl所在的目录添加到编译器里面,如:C:\OpenSSL-Win32\include

    连接器要添加:C:\OpenSSL-Win32\lib\libcrypto.lib

    windows安装版openssl可以在这里下载:https://oomake.com/download/openssl
*/

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <base64.h>
#include <rsas.h>
using namespace std;


int main(void)
{

/*私钥是这样的,换行符被换成了\n

-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCAhDZFe6UuxD2V2Gjf0HSlCxSWR+92+v9NG+B3sXfjS/uzcSZi
XeuyaFmTLB6QeCKA5Snou8uZyMNE3Bvdk1So1DPHHLajsHpERRNXiEVdxd60xEEM
/d/uqtey1napFiTNNStIjIcKb0+8S5Sy4GOsGrscAgRx3wYCAjF6QSqtOQIDAQAB
AoGAKPq/mXlbSyXNI3ZdvpxoTWZSmrb2b0CK3uoYMeJ3gZVtfaMDY9NiAEIQ6gJj
/pooGmS4b9tOCUwAo/jxs74yfKctL3HCoQcBfhAyGiyblby+oJ+i4zw8Sxlzjnp7
yBDZ2lRdDzLEYrab4e6UKTh6YTPNr2nI81JbIxghiA656lcCQQCCjmomitVvOpNm
a3Nnkh3fEl4tRaZNorY202oXJfO2W7EJfZbJg95HUJqC6mG3o0uOcCr7izQw9N0g
cBhJbO37AkEA/AALVSWEjKrWR57HTN8Z8jklkSzeiZVD5efT4ReabyeQQ4ZmoHpU
woOi8e3fo+7NrvTNE8XfBkT4LWY2wHMvWwJAOT42PsX6xTU6sdqFFDFV1ZwZHOKA
A2RHXoyd5J5oWFmlqxKczah7CmvGA4a+56S6mS6HOhmT/a8vUWy0yWTwhwJAZCuU
VaVTOiNSiCeqa3kntCxZLYsbbq9BzSrJA2nBfrvIUb8kHlhiRuvSor5+rohnhEtV
Fa4LCE/0Iv/FddyTjwJAWAUw9vXkEiUhGY9DoPlHynSaaGwpHzgDAPk9meW0AzCy
WB6kxSQIQIrifhQI3aTqbOjkqFW0O9uT9zLHvVzJ0Q==
-----END RSA PRIVATE KEY-----
*/

    string pri = "-----BEGIN RSA PRIVATE KEY-----\nMIICWwIBAAKBgQCAhDZFe6UuxD2V2Gjf0HSlCxSWR+92+v9NG+B3sXfjS/uzcSZi\nXeuyaFmTLB6QeCKA5Snou8uZyMNE3Bvdk1So1DPHHLajsHpERRNXiEVdxd60xEEM\n/d/uqtey1napFiTNNStIjIcKb0+8S5Sy4GOsGrscAgRx3wYCAjF6QSqtOQIDAQAB\nAoGAKPq/mXlbSyXNI3ZdvpxoTWZSmrb2b0CK3uoYMeJ3gZVtfaMDY9NiAEIQ6gJj\n/pooGmS4b9tOCUwAo/jxs74yfKctL3HCoQcBfhAyGiyblby+oJ+i4zw8Sxlzjnp7\nyBDZ2lRdDzLEYrab4e6UKTh6YTPNr2nI81JbIxghiA656lcCQQCCjmomitVvOpNm\na3Nnkh3fEl4tRaZNorY202oXJfO2W7EJfZbJg95HUJqC6mG3o0uOcCr7izQw9N0g\ncBhJbO37AkEA/AALVSWEjKrWR57HTN8Z8jklkSzeiZVD5efT4ReabyeQQ4ZmoHpU\nwoOi8e3fo+7NrvTNE8XfBkT4LWY2wHMvWwJAOT42PsX6xTU6sdqFFDFV1ZwZHOKA\nA2RHXoyd5J5oWFmlqxKczah7CmvGA4a+56S6mS6HOhmT/a8vUWy0yWTwhwJAZCuU\nVaVTOiNSiCeqa3kntCxZLYsbbq9BzSrJA2nBfrvIUb8kHlhiRuvSor5+rohnhEtV\nFa4LCE/0Iv/FddyTjwJAWAUw9vXkEiUhGY9DoPlHynSaaGwpHzgDAPk9meW0AzCy\nWB6kxSQIQIrifhQI3aTqbOjkqFW0O9uT9zLHvVzJ0Q==\n-----END RSA PRIVATE KEY-----";

    //原内容
    string data = "你好中国!";

    cout <<"\n\n私钥加密前:"<<data;

    //私钥加密
     data =rsa_pri_encrypt(data,pri);

    data=base64_encode((const char *)(data.c_str()),data.length());

    cout <<"\n\n私钥加密后:"<<data;


/*
公钥是这样的,换行符也换成了\n
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAhDZFe6UuxD2V2Gjf0HSlCxSW
R+92+v9NG+B3sXfjS/uzcSZiXeuyaFmTLB6QeCKA5Snou8uZyMNE3Bvdk1So1DPH
HLajsHpERRNXiEVdxd60xEEM/d/uqtey1napFiTNNStIjIcKb0+8S5Sy4GOsGrsc
AgRx3wYCAjF6QSqtOQIDAQAB
-----END PUBLIC KEY-----
*/

	std::string pub="-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAhDZFe6UuxD2V2Gjf0HSlCxSW\nR+92+v9NG+B3sXfjS/uzcSZiXeuyaFmTLB6QeCKA5Snou8uZyMNE3Bvdk1So1DPH\nHLajsHpERRNXiEVdxd60xEEM/d/uqtey1napFiTNNStIjIcKb0+8S5Sy4GOsGrsc\nAgRx3wYCAjF6QSqtOQIDAQAB\n-----END PUBLIC KEY-----";

    //base64解码
    data=base64_decode(data);

    //公钥解密
    data=rsa_pub_decrypt(data,pub);

    cout <<"\n\n公钥解密后:"<<data;

    //公钥加密
    data = rsa_pub_encrypt(data,pub);

    //base64加密
    data=base64_encode((const char *)(data.c_str()),data.length());

    cout <<"\n\n公钥加密后:"<<data;

    //base64解密
    data=base64_decode(data);

    //私钥解密后
    data = rsa_pri_decrypt(data,pri);

    cout <<"\n\n私钥解密后:"<<data;

    return 0;
}

 

rsas.h文件

// 私钥加密
std::string rsa_pri_encrypt(const std::string &clearText,  std::string &pubKey)
{
    std::string strRet;
    BIO *keybio = BIO_new_mem_buf((unsigned char *)pubKey.c_str(), -1);

    RSA* rsa = RSA_new();
    rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
    if (!rsa)
    {
            BIO_free_all(keybio);
            return std::string("");
    }

    int len = RSA_size(rsa);
    char *encryptedText = (char *)malloc(len + 1);
    memset(encryptedText, 0, len + 1);

    // 加密
    int ret = RSA_private_encrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
    if (ret >= 0)
        strRet = std::string(encryptedText, ret);

    // 释放内存
    free(encryptedText);
    BIO_free_all(keybio);
    RSA_free(rsa);

    return strRet;
}

// 公钥解密
std::string rsa_pub_decrypt(const std::string &clearText,  std::string &pubKey)
{
    std::string strRet;
    BIO *keybio = BIO_new_mem_buf((unsigned char *)pubKey.c_str(), -1);
    RSA* rsa = RSA_new();

    //rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);//这个失败,二脸萌壁...
    rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
    if (!rsa)
    {

            BIO_free_all(keybio);
            return std::string("");
    }

    int len = RSA_size(rsa);
    char *encryptedText = (char *)malloc(len + 1);
    memset(encryptedText, 0, len + 1);

    //解密
    int ret = RSA_public_decrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);

    if (ret >= 0)
        strRet = std::string(encryptedText, ret);

    // 释放内存
    free(encryptedText);
    BIO_free_all(keybio);
    RSA_free(rsa);

    return strRet;
}
char *Base64Encode(const char* input, int length, bool with_new_line)
{
	 BIO* bmem = NULL;
	 BIO* b64 = NULL;
	 BUF_MEM* bptr = NULL;
	 b64 = BIO_new(BIO_f_base64());
	  if (!with_new_line)
	 {
	  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
	 }
	 bmem = BIO_new(BIO_s_mem());
	 b64 = BIO_push(b64, bmem);
	 BIO_write(b64, input, length);
	 BIO_flush(b64);
	 BIO_get_mem_ptr(b64, &bptr);
	  char * buff = (char *)malloc(bptr->length + 1);
	 memcpy(buff, bptr->data, bptr->length);
	 buff[bptr->length] = 0;
	 BIO_free_all(b64);
	 return buff;
}
char *Base64Decode(char* input, int length, bool with_new_line)
{
	 BIO * b64 = NULL;
	 BIO * bmem = NULL;
	 char * buffer = (char *)malloc(length);
	 memset(buffer, 0, length);
	 b64 = BIO_new(BIO_f_base64());
	  if (!with_new_line)
	 {
	  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
	 }
	 bmem = BIO_new_mem_buf(input, length);
	 bmem = BIO_push(b64, bmem);
	 BIO_read(bmem, buffer, length);
	 BIO_free_all(bmem);
	 return buffer;
}

// 公钥加密
std::string rsa_pub_encrypt(const std::string &clearText,  std::string &pubKey)
{
    std::string strRet;
    BIO *keybio = BIO_new_mem_buf((unsigned char *)pubKey.c_str(), -1);
    RSA* rsa = RSA_new();


    //rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);//这个失败,二脸萌壁..
    rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
    if (!rsa)
    {
            BIO_free_all(keybio);
            return std::string("");
    }

    int len = RSA_size(rsa);
    char *encryptedText = (char *)malloc(len + 1);
    memset(encryptedText, 0, len + 1);

    // 加密函数
    int ret = RSA_public_encrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
    if (ret >= 0)
        strRet = std::string(encryptedText, ret);

    // 释放内存
    free(encryptedText);
    BIO_free_all(keybio);
    RSA_free(rsa);

    return strRet;
}

// 私钥解密
std::string rsa_pri_decrypt(const std::string &cipherText, const std::string &priKey)
{
    std::string strRet;
    RSA *rsa = RSA_new();
    BIO *keybio;
    keybio = BIO_new_mem_buf((unsigned char *)priKey.c_str(), -1);

    rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);

    int len = RSA_size(rsa);
    char *decryptedText = (char *)malloc(len + 1);
    memset(decryptedText, 0, len + 1);

    // 解密函数
    int ret = RSA_private_decrypt(cipherText.length(), (const unsigned char*)cipherText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
    if (ret >= 0)
        strRet = std::string(decryptedText, ret);

    // 释放内存
    free(decryptedText);
    BIO_free_all(keybio);
    RSA_free(rsa);
    return strRet;
}

base64.h文件

/*
使用方法

#include<stdio.h>
#include <string>
#include <iostream>
#include<stdio.h>
using namespace std;


int main() {

  const std::string s = "123\nabc" ;

  std::string encoded = base64_encode((const char*)(s.c_str()), s.length());
  std::string decoded = base64_decode(encoded);

  std::cout << "encoded: " << encoded << std::endl;
  std::cout << "decoded: " << decoded << std::endl;
  return 0;
}
*/

static const std::string base64_chars =
             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
             "abcdefghijklmnopqrstuvwxyz"
             "0123456789+/";

static inline bool is_base64(unsigned char c) {
  return (isalnum(c) || (c == '+') || (c == '/'));
}
                                               //A\nB                          3
std::string base64_encode(char const* bytes_to_encode, int in_len) {
  std::string ret;
  int i = 0;
  int j = 0;
  unsigned char char_array_3[3];
  unsigned char char_array_4[4];

  while (in_len--) {
    char_array_3[i++] = *(bytes_to_encode++);
    if (i == 3) {
      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
      char_array_4[3] = char_array_3[2] & 0x3f;

      for(i = 0; (i < 4) ; i++)
        ret += base64_chars[char_array_4[i]];
      i = 0;
    }
  }

  if (i)
  {
    for(j = i; j < 3; j++)
      char_array_3[j] = '\0';

    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
    char_array_4[3] = char_array_3[2] & 0x3f;

    for (j = 0; (j < i + 1); j++)
      ret += base64_chars[char_array_4[j]];

    while((i++ < 3))
      ret += '=';

  }

  return ret;

}

std::string base64_decode(std::string & encoded_string) {
  int in_len = encoded_string.size();
  int i = 0;
  int j = 0;
  int in_ = 0;
  unsigned char char_array_4[4], char_array_3[3];
  std::string ret;

  while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
    char_array_4[i++] = encoded_string[in_]; in_++;
    if (i ==4) {
      for (i = 0; i <4; i++)
        char_array_4[i] = base64_chars.find(char_array_4[i]);

      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

      for (i = 0; (i < 3); i++)
        ret += char_array_3[i];
      i = 0;
    }
  }

  if (i) {
    for (j = i; j <4; j++)
      char_array_4[j] = 0;

    for (j = 0; j <4; j++)
      char_array_4[j] = base64_chars.find(char_array_4[j]);

    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

    for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
  }

  return ret;
}

 

文章如无特别注明均为原创! 作者: admin, 转载或复制请以 超链接形式 并注明出处 万捷博客
原文地址《 c++使用openssl实现rsa加密解密【windows版】》发布于2019-6-18

打赏作者

评论

游客

看不清楚?点图切换
切换注册

登录

您也可以使用第三方帐号快捷登录

切换登录

注册