当前位置: 首页 > article >正文

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

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);


    //内存形式 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

#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


http://www.kler.cn/news/160103.html

相关文章:

  • 对于多台232modbus仪表低成本通讯的modbus转profinet网关
  • 微服务开发:断路器详解
  • 卡码网语言基础课 | 20. 排队取奶茶
  • Vue的methods中定时器的变量报错问题
  • 十年JK无人知!一朝泳衣天下识
  • 【数据结构】——二叉树特点
  • 区块链创新应用场景不断拓展,实现去中心化
  • 前端三大MV*模式:MVC、mvvm、mvp模式介绍
  • 数据库的设计规范
  • Element-UI 动态控制输入组件类型,定义代码组件、前端模板
  • 02数仓平台Zookeeper
  • prime靶机打靶记录
  • 数字化转型:利用软件电商平台与私有化软件提升竞争力
  • C++ 共享内存ShellCode跨进程传输
  • 54.多级缓存
  • 【PyTorch】数据集
  • 实战oj题——设计循环队列
  • 【Qt之QSqlRelationalTableModel】描述及使用
  • 【微信小程序】保存多张图片到本地相册 wx.saveImageToPhotosAlbum
  • 分支和循环
  • 目标检测——R-CNN算法解读
  • web理论测试
  • Insomnia -- 非常nice的开源 API 调试工具
  • Camunda 7.x 系列【57】流程设计器
  • Axios详解及运用案例
  • 详细学习PyQt5中的多线程
  • ubuntu下QT搭建Android开发环境
  • Linux C语言 42-进程间通信IPC之网络通信(套接字)
  • 基于springboot+vue篮球联盟管理系统源码
  • 基于Vue.js的厦门旅游电子商务预订系统的设计和实现