以1024来对任意长度的数据进行加密,本方法的加密部分是将待加密数据按照117的长度大小进行分割,不足117按实际大小分割加密,解密部分是将数据分割成不同的子串,每个子串的大小为173的固定长度,然后对子串进行解密。
std::string RSA_Client::RSA_Pub_Encrypt_Base64(const std::vector<sDefectItem>& vecDefect, const QString &strPubKey)
{
QJsonArray jsonArray;
StructToJSon(vecDefect, jsonArray);
QByteArray arryPlaintext = QJsonDocument(jsonArray).toJson(QJsonDocument::Compact);
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 nRSALen = RSA_size(pRsa);
char* pEncryptBuf = new char[nRSALen];
memset(pEncryptBuf, 0, nRSALen);
QByteArray jsToBase64 = arryPlaintext.toBase64();
uchar* pPlaintext = (uchar*)jsToBase64.data();
//按nBlock的大小分别进行加密,nBlock大于117取117,不足117取实际大小
int nBlock = nRSALen - 11; //size-11
int nPlaintextLen = jsToBase64.size();
int nCount = (nPlaintextLen / nBlock) + 1;
std::vector<std::string> vecEncryptData;
vecEncryptData.resize(nCount);
// 构建 JSON 数组
QJsonArray json1D; //没有key,只有value
for(int i = 0; i < nCount; i++)
{
int nEncryptLen = 0;
nBlock = (nPlaintextLen > nBlock)?nBlock:nPlaintextLen;
nEncryptLen = RSA_public_encrypt(nBlock, pPlaintext, (uchar*)pEncryptBuf, pRsa, RSA_PKCS1_PADDING);
pPlaintext += nBlock;
nPlaintextLen -= nBlock;
if ( nEncryptLen >= 0 )
{
QByteArray arry(pEncryptBuf, nEncryptLen);
vecEncryptData.at(i) = arry.toBase64();
json1D.append(QString::fromStdString(vecEncryptData.at(i)));
}
}
QByteArray arryjson1D = QJsonDocument(json1D).toJson(QJsonDocument::Compact);
std::string ret = arryjson1D.toBase64();
// 释放内存
delete pEncryptBuf;
BIO_free_all(pKeyBio);
RSA_free(pRsa);
return ret;
}
QString RSA_Client::RSA_Pri_Decrypt_Base64(const std::string &strCiphertext, 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 "";
}
//解密
QByteArray decryptDataArry = QByteArray::fromStdString(strCiphertext);
decryptDataArry = QByteArray::fromBase64(decryptDataArry);
//分割成不同的子串,分别对子串进行解密,子串长度为173
QString strDecryptData = "";
//有多个子串
if(decryptDataArry.toStdString().find(",") != std::string::npos)
{
int nLen = RSA_size(pRsa);
int nStep = decryptDataArry.toStdString().find(",");//175
int nCount = decryptDataArry.toStdString().size() / nStep;
int nDecryptLen = 0;
for(int i = 0; i < nCount; i++)
{
char* pDecryptBuf = new char[nLen];
memset(pDecryptBuf, 0, nLen);
int start = i * nStep + 1;
QByteArray decryptDataSubArry = decryptDataArry.mid(start, nStep-2);
decryptDataSubArry = QByteArray::fromBase64(decryptDataSubArry);
nDecryptLen = RSA_private_decrypt(nLen, (uchar*)decryptDataSubArry.data(), (uchar*)pDecryptBuf, pRsa, RSA_PKCS1_PADDING);
if ( nDecryptLen >= 0 )
{
strDecryptData.append(QByteArray(pDecryptBuf, nDecryptLen));
}
delete pDecryptBuf;
}
}
//只有一个子串
else
{
int nLen = RSA_size(pRsa);
char* pClearBuf = new char[nLen];
memset(pClearBuf, 0, nLen);
//解密
decryptDataArry = QByteArray::fromBase64(decryptDataArry);
uchar* pDecryptData = (uchar*)decryptDataArry.data();
int nSize = RSA_private_decrypt(nLen, pDecryptData, (uchar*)pClearBuf, pRsa, RSA_PKCS1_PADDING);
if ( nSize >= 0 )
{
strDecryptData = QByteArray(pClearBuf, nSize);
}
// 释放内存
delete pClearBuf;
}
strDecryptData = QByteArray::fromBase64(strDecryptData.toLatin1());
// 释放内存
BIO_free_all(pKeyBio);
RSA_free(pRsa);
return strDecryptData;
}