Qt Rsa 加解密方法使用(pkcs1, pkcs8, 以及文件存储和内存存储密钥)

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/

代码地址: https://github.com/heisai/RsaEncipherMent/tree/master

相关推荐
尘中远12 小时前
【Qwt 7.0 系列】坐标轴与刻度系统 —— 刻度引擎、网格、图例与刻度朝内
qt·数据可视化·qcustomplot·qwt·工业软件·科学绘图
sycmancia14 小时前
Qt——多线程间的互斥
开发语言·qt
尘中远19 小时前
【Qwt 7.0 系列】常用图表类型实战 —— 柱状图、散点图、箱线图与直方图
qt·qwt·工业软件·科学绘图
尘中远19 小时前
【Qwt 7.0 系列】交互功能详解 —— 平移、缩放、坐标轴交互与数据拾取
qt·数据可视化·绘图·qcustomplot·qwt·科学绘图
sycmancia19 小时前
Qt——进程与线程的概念
qt
郝学胜-神的一滴20 小时前
Qt 高级编程 034:深耕QWidget底层内核—彻底吃透无边框窗口设计核心原理
开发语言·c++·qt·程序人生·软件开发·用户界面
尘中远21 小时前
【Qwt 7.0 系列】3D 数据可视化 —— OpenGL 高性能三维绘图
qt·3d·qcustomplot·qwt·科学绘图·高性能绘图
满天星830357721 小时前
【Qt】控件(二) (geometry及与frameGeometry的区别)
开发语言·qt
大气的小蜜蜂21 小时前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·qt·sqlite
尘中远21 小时前
【Qwt 7.0 系列】总体架构解析 —— 从单体到三库模块化的演进
qt·matplotlib·绘图·qwt·科学绘图