记录在QT下使用openssl接口实现RSA加解密过程。
1.下载安装openssl 64位windows:https://download.csdn.net/download/lurenyi/87944092
2.创建rsa 密钥
- 生成一个密钥:
openssl genrsa -out test.key 512
这里-out指定生成文件的。需要注意的是这个文件包含了公钥和密钥两部分,也就是说这个文件即可用来加密也可以用来解密。后面的512是生成密钥的长度。
- openssl可以将这个文件中的公钥提取出来:
openssl rsa -in test.key -pubout -out test_pub.key
-in指定输入文件,-out指定提取生成公钥的文件名。至此,我们手上就有了一个公钥,一个私钥(包含公钥)。现在可以将用公钥来加密文件了。
3.创建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 512
class rsa
{
public:
rsa();
~rsa();
QString rsaPubEncrypt(const QString &strPlainData, const QString &strPubKey);
QString rsaPriDecrypt(const QString &strDecryptData, const QString &strPriKey);
};
#endif // RSA_H
.cpp文件
#include "rsa.h"
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;
}
示例
#include "mainwindow.h"
#include <QApplication>
#include <QFile>
#include <QDebug>
#include "rsa.h"
#include <QtWidgets>
#include <QDir>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
/*读取加密文件,私钥解密 测试*/
QString strPriKey = "";
QString strEncryptData = "";
QString strPlainData = "";
rsa *m_rsa = new rsa();
//读取私钥
QFile file1("rsa.key");
file1.open(QIODevice::ReadOnly);
strPriKey = file1.readAll();
//rsapw 读取加密文件
QFile file2("rsapw.txt");
file2.open(QIODevice::ReadOnly);
strEncryptData = file2.readAll();
//解码
strPlainData = m_rsa->rsaPriDecrypt(strEncryptData, strPriKey);
qDebug() << ("strPlainData:"+strPlainData);
file2.close();
file1.close();
MainWindow w;
w.setWindowTitle(strPlainData);
w.show();
return a.exec();
}
4.将openssl的h文件和lib复制到项目下,并添加到项目中
5.在项目pro文件中增加lib
LIBS += -LD:/nasFile/testrsa/lib -llibcrypto
LIBS += -LD:/nasFile/testrsa/lib -llibssl
6.将openssl中的两个dll文件复制到程序目录下
libcrypto-1_1-x64.dll libssl-1_1-x64.dll