QT使用OpenSSL的接口实现RSA的加密解密

QT使用OpenSSL的接口实现RSA的加密解密

首先介绍下命令台下openssl工具的简单使用:

  • 生成一个密钥:

openssl genrsa -out test.key 1024

这里-out指定生成文件的。需要注意的是这个文件包含了公钥和密钥两部分,也就是说这个文件即可用来加密也可以用来解密。后面的1024是生成密钥的长度。

  • openssl可以将这个文件中的公钥提取出来:

openssl rsa -in test.key -pubout -out test_pub.key

-in指定输入文件,-out指定提取生成公钥的文件名。至此,我们手上就有了一个公钥,一个私钥(包含公钥)。现在可以将用公钥来加密文件了。

  • 我在目录中创建一个hello的文本文件,然后利用此前生成的公钥加密文件:

openssl rsautl -encrypt -in hello -inkey test_pub.key -pubin -out hello.en

-in指定要加密的文件,-inkey指定密钥,-pubin表明是用纯公钥文件加密,-out为加密后的文件。

  • 解密文件:

openssl rsautl -decrypt -in hello.en -inkey test.key -out hello.de

-in指定被加密的文件,-inkey指定私钥文件,-out为解密后的文件。

OpenSSL> genrsa -out rsa_private_key.pem 1024
Generating RSA private key, 1024 bit long modulus
....+++++
.................+++++
e is 65537 (0x10001)
OpenSSL> genrsa -out rsa_private_key.pem 1024
Generating RSA private key, 1024 bit long modulus
..............+++++
..........................................+++++
e is 65537 (0x10001)
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
writing RSA key
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -out pkcs8_rsa_private_key.pem -nocrypt
OpenSSL> rsautl -encrypt -in hello.txt -inkey rsa_public_key.pem -pubin -out hello.en
OpenSSL> rsautl -decrypt -in hello.en -inkey rsa_private_key.pem -out hello.de

QT代码实现

test1.pro

QT += core
QT -= gui

CONFIG += c++11

TARGET = test1
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app

SOURCES += main.cpp \
#    rsasignature.cpp \
    rsa.cpp

LIBS += ../windows/x86/bin/libeay32.dll
LIBS += ../windows/x86/bin/ssleay32.dll
INCLUDEPATH += $$quote(../windows/x86/include/)

HEADERS += \
#    rsasignature.h \
    rsa.h

DESTDIR = $$PWD/

main.cpp

#include <QCoreApplication>
#include <QFile>
#include <QDebug>
#include "rsa.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    /*公钥加密,私钥解密 测试案例*/
    QString strPlainData_before = QString::fromLocal8Bit("12dsadas云123345612dsadas12dsadas云123345612dsadas12dsadas云123345612dsadas12dsadas云123345612dsadas12dsadas云213123");
    QString strPubKey = "";
    QString strPriKey = "";
    QString strEncryptData = "";
    QString strPlainData = "";

    rsa *m_rsa = new rsa();

    QFile file("./rsa_public_key.pem");
    file.open(QIODevice::ReadOnly);
    strPubKey = file.readAll();

    QFile file1("./rsa_private_key.pem");
    file1.open(QIODevice::ReadOnly);
    strPriKey = file1.readAll();

    strEncryptData = m_rsa->rsaPubEncrypt(strPlainData_before,strPubKey);
    qDebug() << ("strEncryptData:"+strEncryptData);

    strPlainData = m_rsa->rsaPriDecrypt(strEncryptData, strPriKey);
    qDebug() << ("strPlainData:"+strPlainData);

    file.close();
    file1.close();


    return a.exec();
}

rsa.h

#ifndef RSA_H
#define RSA_H

#include <QString>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>

#define BEGIN_RSA_PUBLIC_KEY    "BEGIN RSA PUBLIC KEY"
#define BEGIN_RSA_PRIVATE_KEY   "BEGIN RSA PRIVATE KEY"
#define BEGIN_PUBLIC_KEY        "BEGIN PUBLIC KEY"
#define BEGIN_PRIVATE_KEY       "BEGIN PRIVATE KEY"
#define KEY_LENGTH              1024

class rsa
{
public:
    rsa();
    ~rsa();

    QString rsaPubEncrypt(const QString &strPlainData, const QString &strPubKey);

    QString rsaPriDecrypt(const QString &strDecryptData, const QString &strPriKey);
};

#endif // RSA_H

rsa.cpp

#include "rsa.h"

rsa::rsa()
{

}

rsa::~rsa()
{

}

QString rsa::rsaPubEncrypt(const QString &strPlainData, const QString &strPubKey)
{
    QByteArray pubKeyArry = strPubKey.toUtf8();
    uchar* pPubKey = (uchar*)pubKeyArry.data();
    BIO* pKeyBio = BIO_new_mem_buf(pPubKey, pubKeyArry.length());
    if (pKeyBio == NULL) {
        return "";
    }


    RSA* pRsa = RSA_new();
    if (strPubKey.contains(BEGIN_RSA_PUBLIC_KEY)) {
        pRsa = PEM_read_bio_RSAPublicKey(pKeyBio, &pRsa, NULL, NULL);

    }
    else {
        pRsa = PEM_read_bio_RSA_PUBKEY(pKeyBio, &pRsa, NULL, NULL);

    }


    if (pRsa == NULL) {
        BIO_free_all(pKeyBio);
        return "";
    }

    int nLen = RSA_size(pRsa);
    char* pEncryptBuf = new char[nLen];


    //加密
    QByteArray plainDataArry = strPlainData.toUtf8();
    int nPlainDataLen = plainDataArry.length();

    int exppadding=nLen;
    if(nPlainDataLen>exppadding-11)
        exppadding=exppadding-11;
    int slice=nPlainDataLen/exppadding;//片数
    if(nPlainDataLen%(exppadding))
        slice++;

    QString strEncryptData = "";
    QByteArray arry;
    for(int i=0; i<slice; i++)
    {
        QByteArray baData = plainDataArry.mid(i*exppadding, exppadding);
        nPlainDataLen = baData.length();
        memset(pEncryptBuf, 0, nLen);
        uchar* pPlainData = (uchar*)baData.data();
        int nSize = RSA_public_encrypt(nPlainDataLen,
                                       pPlainData,
                                       (uchar*)pEncryptBuf,
                                       pRsa,
                                       RSA_PKCS1_PADDING);
        if (nSize >= 0)
        {
            arry.append(QByteArray(pEncryptBuf, nSize));
        }
    }

    strEncryptData += arry.toBase64();
    //释放内存
    delete pEncryptBuf;
    BIO_free_all(pKeyBio);
    RSA_free(pRsa);

    return strEncryptData;
}

QString rsa::rsaPriDecrypt(const QString &strDecryptData, const QString &strPriKey)
{
    QByteArray priKeyArry = strPriKey.toUtf8();
    uchar* pPriKey = (uchar*)priKeyArry.data();
    BIO* pKeyBio = BIO_new_mem_buf(pPriKey, priKeyArry.length());
    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);
    char* pPlainBuf = new char[nLen];

    //解密
    QByteArray decryptDataArry = strDecryptData.toUtf8();
    decryptDataArry = QByteArray::fromBase64(decryptDataArry);
    int nDecryptDataLen = decryptDataArry.length();

    int rsasize=nLen;
    int slice=nDecryptDataLen/rsasize;//片数
    if(nDecryptDataLen%(rsasize))
        slice++;

    QString strPlainData = "";
    for(int i=0; i<slice; i++)
    {
        QByteArray baData = decryptDataArry.mid(i*rsasize, rsasize);
        nDecryptDataLen = baData.length();
        memset(pPlainBuf, 0, nLen);
        uchar* pDecryptData = (uchar*)baData.data();
        int nSize = RSA_private_decrypt(nDecryptDataLen,
                                        pDecryptData,
                                        (uchar*)pPlainBuf,
                                        pRsa,
                                        RSA_PKCS1_PADDING);
        if (nSize >= 0) {
            strPlainData += QByteArray(pPlainBuf, nSize);
        }
    }

    //释放内存
    delete pPlainBuf;
    BIO_free_all(pKeyBio);
    RSA_free(pRsa);

    return strPlainData;
}
posted @ 2021-09-16 17:04  不知云深处  阅读(2265)  评论(1编辑  收藏  举报