Qt RSA 加解密 完整使用
密钥格式:
- pkcs#1
- pkcs#8
如何区分密钥对是PKCS1还是PKCS8?
cpp
通常PKCS1密钥对的开始部分为:-----BEGIN RSA PRIVATE KEY-----或 -----BEGIN RSA PUBLIC KEY-----。
而PKCS8密钥对的开始部分为:-----BEGIN PRIVATE KEY----- 或 -----BEGIN ENCRYPTED PRIVATE KEY----- 或-----BEGIN PUBLIC KEY-----。
加解密方式:
- 文件形式存储密钥
- 内存形式存储密钥
cpp
#ifndef ENCIPHERMENT_H
#define ENCIPHERMENT_H
#include<QObject>
#include"openssl/rsa.h"
#include"openssl/pem.h"
class RsaEncipherMent
{
public:
explicit RsaEncipherMent();
//密钥 以内存的形式存储
QByteArray BioEncrypt(const QByteArray &PlainData, const QByteArray &Pubkey,bool pkcs1 = false);
QByteArray BioDecrypt(const QByteArray &PlainData, const QByteArray &Prikey);
//密钥 以文件的形式存储
QByteArray FileEncrypt(const QByteArray &PlainData, const QByteArray &pem_path,bool pkcs1 = false);
QByteArray FileDecrypt(const QByteArray &PlainData, const QByteArray &pem_path);
//内存形式 pkcs8
const QString public_key = "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALmxDatSZ6vOkzQfXRUlJoR8mbiGOM7FxRX8WolGY3z/tT2CxLE0TFLDz2DcGMKBo68MNfkpCF0+IsH9DimfHFMCAwEAAQ==\n-----END PUBLIC KEY-----\n";
const QString private_key = "-----BEGIN PRIVATE KEY-----\nMIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAubENq1Jnq86TNB9d FSUmhHyZuIY4zsXFFfxaiUZjfP+1PYLEsTRMUsPPYNwYwoGjrww1+SkIXT4iwf0OKZ8cUwIDAQABAkAoTg7qfdN0zjzTVm9s1Ih8v1LaY3/XGcRClmjMXRPhIHynq98B/03mBZ+OXDSGjOtvlLD2Tv70HmwBEHigMn3xAiEA7Vr603otCwBOfy8Pa1/gQqQSWBMLP4oUVw6Rwz6qcUsCIQDIRyhsNI6lBEpF9G+QxneE/agG6bLKaA82cn9K1XKkGQIhAJRTpamgkSNt1qAeTZmBOckLdTc6922GoX1h6m9D6wmPAiEAucDFzRYx9vszqA4+K5jn4YEiBsdZ/EDnWyh2x4GRAoECIAY4wKOCodXaL3W76zaqaiF4xlkOh2/vAMoVirqRNdGA\n-----END PRIVATE KEY-----\n";
//内存形式 pkcs1
const QString public_keypkcs1 = "-----BEGIN RSA PUBLIC KEY-----\nMEgCQQDBTs84K32azWD5PWx44QulreGUwZc1b4iOkwV8EBTw9w9P7vbfA0VN5W27A7ebhEJa287hm1hH/24mE1X5EWUxAgMBAAE=\n-----END RSA PUBLIC KEY-----\n";
const QString private_keypkcs1 = "-----BEGIN RSA PRIVATE KEY-----\nMIIBOwIBAAJBAMFOzzgrfZrNYPk9bHjhC6Wt4ZTBlzVviI6TBXwQFPD3D0/u9t8DRU3lbbsDt5uEQlrbzuGbWEf/biYTVfkRZTECAwEAAQJAK3WaZNhyPrFZ0e8bSfnecnsrMhRr+FmA6/zlyMSc0Kd1/LzlTrCp90vJrEUbLio8+BBBBu5QvqCJDCatNRvYAQIhAPwS5bJTp821w6MWz6CTdn+2NNl/6OuOEU7vFMhojnrBAiEAxFGXtJWKFvTZHQgYTMRWQ1DHvj+MsTxtYWabJUjotnECIQCwCl6B+KxjHIKhfkfIY9PJAy3Li+nV v+TUlGGWSHbgwQIhAME+B3SMVjcuoKBBHZpDER6F33fXmifD8W8Uztauo9MhAiA0r1z3wnJNvyQuxduIhh6G9cCX6RoFXW9cKA3mIy/yHA==\n-----END RSA PRIVATE KEY-----\n";
};
#endif // ENCIPHERMENT_H
cpp
#include"EncipherMent.h"
extern "C"
{
#include <openssl/applink.c>
};
RsaEncipherMent::RsaEncipherMent()
{
}
QByteArray RsaEncipherMent::BioEncrypt(const QByteArray &PlainData, const QByteArray &Pubkey, bool pkcs1 /*= false*/)
{
BIO* pKeyBio = BIO_new_mem_buf(Pubkey.data(), Pubkey.size());
if (pKeyBio == NULL)
{
return "";
}
RSA* pRsa = RSA_new();
if (pkcs1)
{
//pkcs#1
pRsa = PEM_read_bio_RSAPublicKey(pKeyBio, &pRsa, NULL, NULL);
}
else
{
//pkcs#8
pRsa = PEM_read_bio_RSA_PUBKEY(pKeyBio, &pRsa, NULL, NULL);
}
if (pRsa == NULL)
{
BIO_free_all(pKeyBio);
return "";
}
int nLen = RSA_size(pRsa);
QByteArray strEncryptData = "";
strEncryptData.resize(nLen); // 调整输出buf大小
//加密
int nSize = RSA_public_encrypt(PlainData.size(),
(uchar*)PlainData.data(),
(uchar*)strEncryptData.data(),
pRsa,
RSA_PKCS1_PADDING);
//释放内存
BIO_free_all(pKeyBio);
RSA_free(pRsa);
return strEncryptData.toBase64();
}
QByteArray RsaEncipherMent::BioDecrypt(const QByteArray &PlainData, const QByteArray &Prikey)
{
BIO* pKeyBio = BIO_new_mem_buf(Prikey.data(), Prikey.size());
if (pKeyBio == NULL)
{
return "";
}
RSA* pRsa = RSA_new();
pRsa = PEM_read_bio_RSAPrivateKey(pKeyBio, &pRsa, NULL, NULL);
if (pRsa == NULL)
{
BIO_free_all(pKeyBio);
return "";
}
int nLen = RSA_size(pRsa);
QByteArray strEncryptData = "";
strEncryptData.resize(nLen);
//解密
int nSize = RSA_private_decrypt(PlainData.size(),
(uchar*)PlainData.data(),
(uchar*)strEncryptData.data(),
pRsa,
RSA_PKCS1_PADDING);
//释放内存
BIO_free_all(pKeyBio);
RSA_free(pRsa);
return strEncryptData.mid(0,nSize);
}
QByteArray RsaEncipherMent::FileEncrypt(const QByteArray &PlainData, const QByteArray &pem_path,bool pkcs1)
{
RSA * rsa = NULL;
FILE* fp = NULL;
char* en = NULL;
if((fp = fopen((char*)pem_path.data(),"rb")) == NULL)
{
return "";
}
if(pkcs1)
{
if((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) == NULL)
{
return "";
}
}
else
{
if((rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL)) == NULL)
{
return "";
}
}
int rsa_len = RSA_size(rsa);
QByteArray encode;
encode.resize(rsa_len);
int reasult = RSA_public_encrypt(PlainData.size(), (unsigned char*)PlainData.data(), (unsigned char*)encode.data(), rsa, RSA_PKCS1_PADDING);
if(reasult == -1)
{
return "";
}
RSA_free(rsa);
return encode.toBase64();
}
QByteArray RsaEncipherMent::FileDecrypt(const QByteArray &PlainData, const QByteArray &pem_path)
{
RSA *rsa = NULL;
FILE*fp = NULL;
char*de = NULL;
int rsa_len = 0;
if((fp = fopen(pem_path.data(),"rb")) == NULL)
{
return "read fail";
}
if((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL)
{
return NULL;
}
rsa_len = RSA_size(rsa);
QByteArray decode;
decode.resize(rsa_len);
int reasult = RSA_private_decrypt(PlainData.size(), (unsigned char*)PlainData.data(), (unsigned char*)decode.data(), rsa, RSA_PKCS1_PADDING);
if( reasult==-1)
{
return "";
}
RSA_free(rsa);
fclose(fp);
return decode.mid(0,reasult);
}
密钥生成地址: https://uutool.cn/rsa-generate/