轉載來自:http://blog.wjsrs.com/post-43.html
rsas.h
#pragma once // 私鑰加密 #include <openssl/aes.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/err.h> #include <openssl/evp.h> #include <openssl/bio.h> #include <openssl/buffer.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; } // 公鑰加密 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; }
#pragma once // 私鑰加密 #include <openssl/aes.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/err.h> #include <openssl/evp.h> #include <openssl/bio.h> #include <openssl/buffer.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; } // 公鑰加密 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
#pragma once /* 使用方法 #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; }
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; #pragma comment(lib,"libssl.lib") #pragma comment(lib,"libcrypto.lib") int main() { /*私鑰是這樣的,換行符被換成了\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 = "--account-password=abcd:12346789abccgheu."; 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; }