Qt RSA 加解密 完整使用
密钥格式:
- pkcs#1
- pkcs#8
如何区分密钥对是PKCS1还是PKCS8?
通常PKCS1密钥对的开始部分为:-----BEGIN RSA PRIVATE KEY-----或 -----BEGIN RSA PUBLIC KEY-----。而PKCS8密钥对的开始部分为:-----BEGIN PRIVATE KEY----- 或 -----BEGIN ENCRYPTED PRIVATE KEY----- 或-----BEGIN PUBLIC KEY-----。
加解密方式:
- 文件形式存储密钥
- 内存形式存储密钥
#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);//内存形式 pkcs8const 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";//内存形式 pkcs1const 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
#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#1pRsa = PEM_read_bio_RSAPublicKey(pKeyBio, &pRsa, NULL, NULL);}else{//pkcs#8pRsa = 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/
代码地址: https://github.com/heisai/RsaEncipherMent/tree/master