rsa加密的public key格式有多种,常见的有两种,
一种密钥头为‘-----BEGIN RSA PUBLIC KEY-----’,
一种开头为‘-----BEGIN PUBLIC KEY-----’,
二者分别对应rsa的PKCS#1和PKCS#8格式。
使用openssl库加载rsa的公钥时,使用的函数也不同。以字符串公钥为例,对PKCS#1格式的密钥加载使用PEM_read_bio_RSAPublicKey()函数,对PKCS#8格式公钥的加载使用PEM_read_bio_RSA_PUBKEY()函数。
对于不那么熟悉rsa的同学,使用时注意区分者,可以减少不必要的麻烦。
// ---- rsa非对称加解密 ---- //
#define KEY_LENGTH 512 // 密钥长度
#define PUB_KEY_FILE "pubkey.pem" // 公钥路径
#define PRI_KEY_FILE "prikey.pem" // 私钥路径
生成密钥对方法:
// 函数方法生成密钥对
void rsa::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);
}
1、已知公钥密钥 进行加密 和解密
加载公钥
#include <openssl/pem.h>
#include <openssl/err.h>
RSA* rsa::CreatePubKey()
{
RSA*pPubKey_ = NULL;
BIO* bp = NULL;
std::string strPublicKey = "-----BEGIN RSA PUBLIC KEY-----\n\
MEYCQQDtWr6MU1o9GQdepJMdrRJsDyA9/ENMNxKd5+Vja794dJGQF4rPEY/1jjUZ\n\
NrDpY8z3r+2zc9BoKlc1oVs+0Ri7AgED\n\
-----END RSA PUBLIC KEY-----\n";
char *chPublicKey = const_cast<char *>(strPublicKey.c_str());
if ((bp = BIO_new_mem_buf(chPublicKey, -1)) == NULL)
{
printf("BIO_new_mem_buf failed!\n");
return pPubKey_;
}
//PEM_read_bio_RSAPublicKey
pPubKey_ = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL);
if (NULL == pPubKey_)
{
ERR_load_crypto_strings();
char errBuf[512];
ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf));
printf("load public key failed[%s]\n", errBuf);
return pPubKey_;
}
BIO_free_all(bp);
return pPubKey_;
}
加载密钥
RSA* rsa::CreatePriKey()
{
RSA*pPubKey_ = NULL;
BIO* bp = NULL;
std::string strPublicKey = "-----BEGIN RSA PRIVATE KEY-----\n\
MIIBOgIBAAJBAO1avoxTWj0ZB16kkx2tEmwPID38Q0w3Ep3n5WNrv3h0kZAXis8R\n\
j/WONRk2sOljzPev7bNz0GgqVzWhWz7RGLsCAQMCQQCePH8IN5F+EK+UbbdpHgxI\n\
ChV+qCzdegxpRUOXnSpQTG2vcBaQlHDWHUurJCBECokOsDWZhXtMOI5ruPhMHEoL\n\
AiEA+V181QCm02k1S2UhLQfZ6spLi7NUP+J5vvx4GBJ7VKMCIQDzq3KT9YwTSyz4\n\
M19Te3oUl1wRmddXk1vCl5POuitVCQIhAKY+UzirGeJGI4eYwMiv5pyG3QfM4tVB\n\
pn9S+rq2/OMXAiEAonJMYqOyt4dzUCI/jPz8Dbo9YRE6OmI9LGUNNHwc41sCIA3l\n\
XdHvymRjRzXXSlf1IvW7QSEwhYO0ifGXsrTd3t5d\n\
-----END RSA PRIVATE KEY-----\n";
char *chPublicKey = const_cast<char *>(strPublicKey.c_str());
if ((bp = BIO_new_mem_buf(chPublicKey, -1)) == NULL)
{
printf("BIO_new_mem_buf failed!\n");
return pPubKey_;
}
pPubKey_ = PEM_read_bio_RSAPrivateKey(bp, NULL, NULL, NULL);
if (NULL == pPubKey_)
{
ERR_load_crypto_strings();
char errBuf[512];
ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf));
printf("load public key failed[%s]\n", errBuf);
return pPubKey_;
}
BIO_free_all(bp);
return pPubKey_;
}
公钥加密:
// 公钥加密
std::string rsa::rsa_pub_encrypt(const std::string &clearText)
{
std::string strRet;
RSA* rsa = CreatePubKey();
int len = RSA_size(rsa);
//int len = 1028;
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::rsa_pri_decrypt(const std::string &cipherText)
{
std::string strRet;
RSA* rsa = CreatePriKey();
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;
}
2、从文件pubkey.pem 和prikey.pem 读取公钥和密钥
公钥加密:
// 公钥加密
std::string rsa::rsa_pub_encrypt(const std::string &clearText, std::string &pubKey)
{
std::string strRet;
BIO * key = NULL;
RSA * rsa = NULL;
key = BIO_new(BIO_s_file());
BIO_read_filename(key, PUB_KEY_FILE);
rsa = PEM_read_bio_RSAPublicKey(key, NULL, NULL, NULL);
int len = RSA_size(rsa);
char *decryptedText = (char *)malloc(len + 1);
memset(decryptedText, 0, len + 1);
int lenf = clearText.length();
// 加密函数
int ret = RSA_public_encrypt(lenf, (const unsigned char*)clearText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_OAEP_PADDING);
if (ret >= 0)
strRet = std::string(decryptedText, ret);
// 释放内存
free(decryptedText);
BIO_free_all(key);
RSA_free(rsa);
return strRet;
//方式二
/*std::string strRet;
RSA *rsa;
BIO * key = NULL;
FILE *fp;
if ((fp = fopen(PUB_KEY_FILE, "r")) == NULL) {
return "";
}
rsa = PEM_read_RSAPublicKey(fp, NULL, 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(key);
RSA_free(rsa);
return strRet;*/
}
私钥解密:
// 私钥解密
std::string rsa::rsa_pri_decrypt(const std::string &cipherText, const std::string &priKey)
{
//方式一
std::string strRet;
BIO * key = NULL;
RSA * rsa = NULL;
key = BIO_new(BIO_s_file());
BIO_read_filename(key, PRI_KEY_FILE);
rsa = PEM_read_bio_RSAPrivateKey(key, NULL, NULL, NULL);
int len = RSA_size(rsa);
char *decryptedText = (char *)malloc(len + 1);
memset(decryptedText, 0, len + 1);
// 解密函数
int lenf = cipherText.length();
int ret = RSA_private_decrypt(lenf, (const unsigned char*)cipherText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_OAEP_PADDING);
if (ret >= 0)
strRet = std::string(decryptedText, ret);
/
// 释放内存
free(decryptedText);
BIO_free_all(key);
RSA_free(rsa);
return strRet;
/* std::string strRet;
BIO * key = NULL;
RSA * rsa = NULL;
key = BIO_new(BIO_s_file());
BIO_read_filename(key, PUB_KEY_FILE);
rsa = PEM_read_bio_RSAPublicKey(key, NULL, NULL, NULL);
int len = RSA_size(rsa);
char *decryptedText = (char *)malloc(len + 1);
memset(decryptedText, 0, len + 1);
// 解密函数
int ret = RSA_public_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(key);
RSA_free(rsa);
return strRet;*/
}