#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <openssl/rsa.h> #include <openssl/err.h> #include <openssl/objects.h> #pragma comment(lib,"libssl.lib") #pragma comment(lib,"libcrypto.lib") namespace dakuang {} void printHex(const unsigned char* pBuf, int nLen) { for (int i = 0; i < nLen; ++i) { printf("%02x", pBuf[i]); } printf("\n"); } #include <iostream> #include <memory> struct Sample { Sample() { std::cout << "Sample\n"; } ~Sample() { std::cout << "~Sample\n"; } int a{ 1 }; }; void deleter(Sample* x) { std::cout << "Custom Deleter\n"; delete[] x; } #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <openssl/rsa.h> #include <openssl/err.h> #include <openssl/x509.h> #include <string.h> #include <openssl/rsa.h> #include <openssl/aes.h> #include <cassert> #include <string> #include <vector> #include "openssl/md5.h" #include "openssl/sha.h" #include "openssl/des.h" #include "openssl/rsa.h" #include "openssl/pem.h" // ---- rsa非对称加解密 ---- // #define KEY_LENGTH 2048 // 密钥长度 #define PUB_KEY_FILE "pubkey.pem" // 公钥路径 #define PRI_KEY_FILE "prikey.pem" // 私钥路径 // 函数方法生成密钥对 void generateRSAKey(std::string strKey[2]) { // 公私密钥对 size_t pri_len; size_t pub_len; char* pri_key = NULL; char* pub_key = NULL; // 生成密钥对 RSA* keypair = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL); BIO* pri = BIO_new(BIO_s_mem()); BIO* pub = BIO_new(BIO_s_mem()); PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL); PEM_write_bio_RSAPublicKey(pub, keypair); // 获取长度 pri_len = BIO_pending(pri); pub_len = BIO_pending(pub); // 密钥对读取到字符串 pri_key = (char*)malloc(pri_len + 1); pub_key = (char*)malloc(pub_len + 1); BIO_read(pri, pri_key, pri_len); BIO_read(pub, pub_key, pub_len); pri_key[pri_len] = '\0'; pub_key[pub_len] = '\0'; // 存储密钥对 strKey[0] = pub_key; strKey[1] = pri_key; // 存储到磁盘(这种方式存储的是begin rsa public key/ begin rsa private key开头的) FILE* pubFile = fopen(PUB_KEY_FILE, "w"); if (pubFile == NULL) { //assert(false); return; } fputs(pub_key, pubFile); fclose(pubFile); FILE* priFile = fopen(PRI_KEY_FILE, "w"); if (priFile == NULL) { //assert(false); return; } fputs(pri_key, priFile); fclose(priFile); // 内存释放 RSA_free(keypair); BIO_free_all(pub); BIO_free_all(pri); free(pri_key); free(pub_key); } // 命令行方法生成公私钥对(begin public key/ begin private key) // 找到openssl命令行工具,运行以下 // openssl genrsa -out prikey.pem 1024 // openssl rsa - in privkey.pem - pubout - out pubkey.pem // 公钥加密 std::string rsa_pub_encrypt(const std::string& clearText, const std::string& pubKey) { std::string strRet; RSA* rsa = NULL; BIO* keybio = BIO_new_mem_buf((unsigned char*)pubKey.c_str(), -1); // 此处有三种方法 // 1, 读取内存里生成的密钥对,再从内存生成rsa // 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa // 3,直接从读取文件指针生成rsa RSA* pRSAPublicKey = RSA_new(); rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL); 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); // 此处有三种方法 // 1, 读取内存里生成的密钥对,再从内存生成rsa // 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa // 3,直接从读取文件指针生成rsa 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; } int main() { // // 1. 产生RSA密钥对 // // 产生512字节公钥指数为RSA_F4的密钥对,公钥指数有RSA_F4和RSA_3两种 // // 我不清楚它们的区别,就随便选定RSA_F4 // // 可以使用RSA_print_fp()看看RSA里面的东西 // RSA* ClientRsa = RSA_generate_key(2048, RSA_F4, NULL, NULL); // // // --------- // // 2. 从RSA结构中提取公钥到BUFF,以便将它传输给对方 // // 512位的RSA其公钥提出出来长度是74字节,而私钥提取出来有超过300字节 // // 为保险起见,建议给它们预留一个512字节的空间 // unsigned char PublicKey[5120]; // unsigned char* PKey = PublicKey; // 注意这个指针不是多余,是特意要这样做的, // int PublicKeyLen = i2d_RSAPublicKey(ClientRsa, &PKey); // // // 不能采用下面的方法,因为i2d_RSAPublicKey()会修改PublicKey的值 // // 所以要引入PKey,让它作为替死鬼 // // unsigned char *PublicKey = (unsigned char *)malloc(512); // // int PublicKeyLen = i2d_RSAPublicKey(ClientRsa, &PublicKey); // // // 逐个字节打印PublicKey信息 // printf("PublicKeyBuff, Len=%d\n", PublicKeyLen); // for (int i = 0; i < PublicKeyLen; i++) // { // printf("0x%02x, ", *(PublicKey + i)); // } // printf("\n"); // // // // --------- // // 3. 跟据上面提出的公钥信息PublicKey构造一个新RSA密钥(这个密钥结构只有公钥信息) // PKey = PublicKey; // RSA* EncryptRsa = d2i_RSAPublicKey(NULL, (const unsigned char**)&PKey, PublicKeyLen); // // // --------- // // 4. 使用EncryptRsa加密数据,再使用ClientRsa解密数据 // // 注意, RSA加密/解密的数据长度是有限制,例如512位的RSA就只能最多能加密解密64字节的数据 // // 如果采用RSA_NO_PADDING加密方式,512位的RSA就只能加密长度等于64的数据 // // 这个长度可以使用RSA_size()来获得 // unsigned char InBuff[640], OutBuff[640]; // // strcpy((char*)InBuff, "1234567890abcdefghiklmnopqrstuvwxyz.\ //1234567890abcdefghiklmnopqrstuvwxyz.\ //1234567890abcdefghiklmnopqrstuvwxyz.\ //1234567890abcdefghiklmnopqrstuvwxyz.\ //1234567890abcdefghiklmnopqrstuvwxyz.\ //1234567890abcdefghiklmnopqrstuvwxyz.\ //1234567890abcdefghiklmnopqrstuvwxyz.\ //1234567890abcdefghiklmnopqrstuvwxyz.\ //1234567890abcdefghiklmnopqrstuvwxyz.\ //1234567890abcdefghiklmnopqrstuvwxyz.\ //1234567890abcdefghiklmnopqrstuvwxyz.\ //1234567890abcdefghiklmnopqrstuvwxyz."); // RSA_public_encrypt(640, (const unsigned char*)InBuff, OutBuff, EncryptRsa, RSA_NO_PADDING); // 加密 // // memset(InBuff, 0, sizeof(InBuff)); // RSA_private_decrypt(640, (const unsigned char*)OutBuff, InBuff, ClientRsa, RSA_NO_PADDING); // 解密 // printf("RSADecrypt OK: %s \n", InBuff); // // // //// ---------- // //// 5. 利用随机32字节Seed来产生256位的AES密钥对 // //unsigned char Seed[32]; // 可以采用Rand()等方法来构造随机信息 // //AES_KEY AESEncryptKey, AESDecryptKey; // //AES_set_encrypt_key(Seed, 256, &AESEncryptKey); // //AES_set_decrypt_key(Seed, 256, &AESDecryptKey); // // //// ---------- // //// 6. 使用AES密钥对来加密/解密数据 // //// 注意,256位的AES密钥只能加密/解密16字节长的数据 // //strcpy((char*)InBuff, "a1b2c3d4e5f6g7h8?"); // //AES_encrypt(InBuff, OutBuff, &AESEncryptKey); // // //memset(InBuff, 0, sizeof(InBuff)); // //AES_decrypt(OutBuff, InBuff, &AESDecryptKey); // //printf("AESDecrypt OK: %s \n", InBuff); // // // // ---------- // // 7. 谨记要释放RSA结构 // RSA_free(ClientRsa); // RSA_free(EncryptRsa); std::string encryptText; std::string encryptHexText; std::string decryptText; // 原始明文 std::string srcText = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; // rsa std::cout << "=== rsa加解密 ===" << std::endl; std::string key[2]; generateRSAKey(key); std::cout << "公钥: " << std::endl; std::cout << key[0] << std::endl; std::cout << key[0].length() << std::endl; std::cout << "私钥: " << std::endl; std::cout << key[1] << std::endl; encryptText = rsa_pub_encrypt(srcText, key[0]); std::cout << "加密字符: " << std::endl; std::cout << encryptText << std::endl; decryptText = rsa_pri_decrypt(encryptText, key[1]); std::cout << "解密字符: " << std::endl; std::cout << decryptText << std::endl; return(0); }
标签:RSA,pub,rsa,char,key,include,加密算法 From: https://www.cnblogs.com/yewu1/p/17321908.html