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

相关推荐
锦亦之223310 小时前
QT+OSG+OSG-earth如何在窗口显示一个地球
开发语言·qt
柳鲲鹏13 小时前
编译成功!QT/6.7.2/Creator编译Windows64 MySQL驱动(MinGW版)
开发语言·qt·mysql
三玖诶13 小时前
如何在 Qt 的 QListWidget 中逐行添加和显示数据
开发语言·qt
阳光开朗_大男孩儿19 小时前
DBUS属性原理
linux·服务器·前端·数据库·qt
Alphapeople20 小时前
Qt Modbus
开发语言·qt
竹林海中敲代码20 小时前
Qt Creator 集成开发环境 常见问题
qt·qt工具常见问题
竹林海中敲代码1 天前
Qt安卓开发连接手机调试(红米K60为例)
android·qt·智能手机
长沙红胖子Qt1 天前
关于 Qt运行加载内存较大崩溃添加扩大运行内存 的解决方法
开发语言·qt·qt扩大运行内存
gopher95111 天前
qt相关面试题
开发语言·qt·面试
三玖诶1 天前
在 Qt 中使用 QLabel 设置 GIF 动态背景
开发语言·qt·命令模式