您的位置:首页 > 编程语言 > Qt开发

QT中用openssl做rsa加密解密

2017-12-27 11:02 573 查看
首先,你得安装openssl,去官网下载最新版本就行,

安装完成后用命令行打开到openssl安装目录,先生成私钥,私钥保存到此目录的private.pem中,密钥长度2048位,然后再从私钥中提取公钥,公钥保存到此目录的public.pem中,当然,文件名称自己定。

按照上述命令生成好私钥公钥文件后,直接编辑打开把密钥复制出来用,或者在程序中直接用公钥私钥文件加载RSA对象。

QT中数据类型转换还是很不好搞的,下面代码中,密钥,明文,密文我都用的QString作为参数传入,分片加密和解密都有,也是我在项目中使用的版本,我刚学QT不就,如果各位发现我写的有问题的地方,请指正。

代码:

#include <openssl/rsa.h>

#include <openssl/pem.h>

#include <openssl/bn.h>

#include <openssl/bio.h>

#include <openssl/evp.h>

#include "openssl/ssl.h"

#include "openssl/err.h"


/**

* @brief RSASignature::createRSA 载入密钥

* @param key 密钥

* @param publi 公钥1 私钥0

* @return

*/

RSA * RSASignature::createRSA(unsigned char * key,int publi)

{

RSA *rsa= NULL;

BIO *keybio ;

keybio = BIO_new_mem_buf(key, -1);

if (keybio==NULL)

{

qDebug()<< "Failed to create key BIO";

return 0;

}

if(publi)

{

rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);

}

else

{

rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);

}

if(rsa == NULL)

{

qDebug()<< "Failed to create RSA";

}


return rsa;

}

/**

* @brief RSASignature::public_encrypt 公钥加密

* @param data 待加密数据

* @param data_len 待加密的数据长度

* @param key 公钥

* @param encrypted 加密后的数据

* @return 加密长度

*/

int RSASignature::public_encrypt(unsigned char * data,int data_len,unsigned char * key, unsigned char *encrypted)

{

RSA * rsa = createRSA(key,1);

if(rsa==NULL)

return 0;

result = RSA_public_encrypt(data_len,data,encrypted,rsa,padding);

return result;

}

/**

* @brief RSASignature::private_decrypt 私钥解密

* @param enc_data 待解密数据

* @param data_len 待解密数据长度

* @param key 私钥

* @param decrypted 解密后的数据

* @return

*/

int RSASignature::private_decrypt(unsigned char * enc_data,int data_len,unsigned char * key, unsigned char *decrypted)

{

RSA * rsa = createRSA(key,0);

if(rsa==NULL)

return 0;

int  result = RSA_private_decrypt(data_len,enc_data,decrypted,rsa,padding);

return result;

}


/**

* @brief RSASignature::private_encrypt 私钥加密

* @param data 待加密数据

* @param data_len 待加密数据长度

* @param key 私钥

* @param encrypted 加密后数据

* @return

*/

int RSASignature::private_encrypt(unsigned char * data,int data_len,unsigned char * key, unsigned char *encrypted)

{

RSA * rsa = createRSA(key,0);

if(rsa==NULL)

return 0;

qDebug()<<RSA_size(rsa);

int result = RSA_private_encrypt(data_len,data,encrypted,rsa,padding);

return result;

}

/**

* @brief RSASignature::public_decrypt 公钥解密

* @param enc_data 待解密数据

* @param data_len 待解密数据长度

* @param key 公钥

* @param decrypted 解密后的数据

* @return

*/

int RSASignature::public_decrypt(unsigned char * enc_data,int data_len,unsigned char * key, unsigned char *decrypted)

{

RSA * rsa = createRSA(key,1);

if(rsa==NULL)

return 0;

qDebug()<<RSA_size(rsa);

int  result = RSA_public_decrypt(data_len,enc_data,decrypted,rsa,padding);

return result;

}

/**

* @brief RSASignature::public_encrypt 公钥加密

* @param data 待加密数据

* @param keystr 公钥

* @param encrypted 加密后数据

* @return

*/

int RSASignature::public_encrypt(QString &data,QString &keystr,QString &encrypted)

{

QByteArray keydata=keystr.toLocal8Bit();

unsigned char *key= (unsigned char*)strdup(keydata.constData());//密钥

RSA * rsa = createRSA(key,1);

if(rsa==NULL)

return 0;

free(key);

int rsasize=RSA_size(rsa);

int exppadding=rsasize;

int result=-1;

QByteArray decdata=QByteArray::fromStdString(data.toStdString()).toBase64(QByteArray::Base64Encoding);

QByteArray signByteArray;

int data_len=decdata.length();

if(data_len>exppadding-11)

exppadding=exppadding-11;

int b=0;

int s=data_len/(exppadding);//片数

if(data_len%(exppadding))

s++;

for(int i=0;i<s;i++)

{

QByteArray subdata={0};

for(int j=0;j<exppadding;j++)

{

if(i*exppadding+j>data_len)

break;

subdata[j]=decdata[j+i*exppadding];

}

unsigned char *smldata=(unsigned char*)strdup(subdata.constData());//数据分片

unsigned char smlencrypted[1024]={0};//片段加密数据

b +=RSA_public_encrypt(exppadding,smldata,smlencrypted,rsa,padding);

if(b>0)

{

QByteArray subarray=QByteArray::fromRawData((const char *)smlencrypted,rsasize);

signByteArray.append(subarray);

}

free(smldata);

}

QString str(signByteArray.toHex());

qDebug()<<str;

encrypted.append(str);

result=b;

return result;

}

/**

* @brief RSASignature::private_decrypt 私钥解密

* @param data 待解密数据

* @param keystr 私钥

* @param decrypted 解密后的数据

* @return

*/

int RSASignature::private_decrypt(QString &data,QString &keystr,QString &decrypted)

{

QByteArray keydata=keystr.toLocal8Bit();

unsigned char *key= (unsigned char*)strdup(keydata.constData());//密钥

RSA * rsa = createRSA(key,0);

if(rsa==NULL)

return 0;

free(key);

int rsasize=RSA_size(rsa);

int result=-1;

QByteArray encdata=QByteArray::fromHex(QByteArray::fromStdString( data.toStdString()));

QByteArray signByteArray;

int data_len=encdata.length();

int b=0;

int s=data_len/(rsasize);//片数

if(data_len%(rsasize))

s++;

for(int i=0;i<s;i++)

{

QByteArray subdata={0};

for(int j=0;j<rsasize;j++)

{

if(i*rsasize+j>data_len)

break;

subdata[j]=encdata[j+i*rsasize];

}

unsigned char *smldata=(unsigned char*)subdata.data();//(unsigned char*)strdup(subdata.constData());//数据分片

unsigned char smlencrypted[1024]={0};//片段加密数据

b +=RSA_private_decrypt(rsasize,smldata,smlencrypted,rsa,padding);

if(b>0)

{

QByteArray decdata((char*)smlencrypted);

signByteArray.append(decdata);

}

}

QByteArray b1= QByteArray::fromBase64(signByteArray,QByteArray::Base64Encoding);

std::string str=b1.toStdString();

decrypted.append(QString::fromStdString( str));

result=b;

return result;

}

/**

* @brief RSASignature::private_encrypt 私钥加密

* @param data 待加密数据

* @param keystr 私钥

* @param encrypted 解密后的数据

* @return

*/

int RSASignature::private_encrypt(QString &data,QString &keystr,QString &encrypted)

{

QByteArray keydata=keystr.toLocal8Bit();

unsigned char *key= (unsigned char*)strdup(keydata.constData());//密钥

RSA * rsa = createRSA(key,0);

if(rsa==NULL)

return 0;

free(key);

int rsasize=RSA_size(rsa);

int exppadding=rsasize;

int result=-1;

QByteArray decdata=QByteArray::fromStdString(data.toStdString()).toBase64(QByteArray::Base64Encoding);

QByteArray signByteArray;

int data_len=decdata.length();

if(data_len>exppadding-11)//padding占11位

exppadding=exppadding-11;

int b=0;

int s=data_len/(exppadding);//片数

if(data_len%(exppadding))

s++;

for(int i=0;i<s;i++)

{

//分片加密

QByteArray subdata={0};

for(int j=0;j<exppadding;j++)

{

if(i*exppadding+j>data_len)

break;

subdata[j]=decdata[j+i*exppadding];

}

unsigned char *smldata=(unsigned char*)strdup(subdata.constData());//数据分片

unsigned char smlencrypted[1024]={0};//片段加密数据

b +=RSA_private_encrypt(exppadding,smldata,smlencrypted,rsa,padding);

if(b>0)

{

QByteArray subarray=QByteArray::fromRawData((const char *)smlencrypted,rsasize);

signByteArray.append(subarray);

}

free(smldata);

}

QString str(signByteArray.toHex());

qDebug()<<str;

encrypted.append(str);

result=b;

return result;

}

/**

* @brief RSASignature::public_decrypt 公钥解密

* @param data 待解密数据

* @param keystr 公钥

* @param decrypted 解密后的数据

* @return

*/

int RSASignature::public_decrypt(QString &data,QString &keystr,QString &decrypted)

{

QByteArray keydata=keystr.toLocal8Bit();

unsigned char *key= (unsigned char*)strdup(keydata.constData());//密钥

RSA * rsa = createRSA(key,1);

if(rsa==NULL)

return 0;

free(key);

int rsasize=RSA_size(rsa);

int result=-1;

QByteArray encdata=QByteArray::fromHex(QByteArray::fromStdString( data.toStdString()));

QByteArray signByteArray;

int data_len=encdata.length();

int b=0;

int s=data_len/(rsasize);//片数

if(data_len%(rsasize))

s++;

for(int i=0;i<s;i++)

{

QByteArray subdata={0};

for(int j=0;j<rsasize;j++)

{

if(i*rsasize+j>data_len)

break;

subdata[j]=encdata[j+i*rsasize];

}

unsigned char *smldata=(unsigned char*)subdata.data();//(unsigned char*)strdup(subdata.constData());//数据分片

unsigned char smlencrypted[1024]={0};//片段加密数据

b +=RSA_public_decrypt(rsasize,smldata,smlencrypted,rsa,padding);

if(b>0)

{

QByteArray decdata((char*)smlencrypted);

signByteArray.append(decdata);

}

}

QByteArray b1= QByteArray::fromBase64(signByteArray,QByteArray::Base64Encoding);

std::string str=b1.toStdString();

decrypted.append(QString::fromStdString( str));

result=b;

return result;

}

请自己提取头文件。

前面那段原始的加密解密方法未提供数据分片,所以只能加密长度小于245的字符数组
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  qt openssl rsa