RSA加密V2

以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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值