QT 中使用 rsa 加密 签名

代码

头文件

#ifndef RSA_H
#define RSA_H

#include 
#include 
#include 
#include
#include 
// define rsa public key
#define BEGIN_RSA_PUBLIC_KEY    "BEGIN RSA PUBLIC KEY"      //
#define BEGIN_PUBLIC_KEY        "BEGIN PUBLIC KEY"          // 公钥头部
#define KEY_LENGTH              1024                        // 密钥长度

class rsa
{
public:

    rsa();
    // 生成一对公钥和私钥
    static bool MakeUpRsaKey (QString& publicKey, QString& privateKey);
    /**
    * @brief rsa_pri_encrypt 私钥加密
    * @param strClearData 明文
    * @param strPriKey 私钥
    * @return 加密后数据(base64格式)
    */
    static QString rsa_pri_encrypt_base64 (const QString& strClearData, const QString& strPriKey);
    /**
    * @brief rsa_pub_decrypt 公钥解密
    * @param strDecrypt 待解密数据(base64格式)
    * @param strPubKey 公钥钥
    * @return 明文
    */
    static QString rsa_pub_decrypt_base64 (const QString& strDecryptData, const QString& strPubKey);
    /**
    * @brief rsa_pub_encrypt 公钥加密
    * @param strClearData 明文
    * @param strPubKey 私钥
    * @return 加密后数据(base64格式)
    */
    static QString rsa_pub_encrypt_base64 (const QString& strClearData, const QString& strPubKey);
    /**
    * @brief rsa_pri_decrypt 私钥解密
    * @param strDecrypt 待解密数据(base64格式)
    * @param strPriKey 私钥
    * @return 明文
    */
    static QString rsa_pri_decrypt_base64 (const QString& strDecryptData, const QString& strPriKey);

    // 签名 strData 原始字符串;  strSigned 签名结果 ; strPriKey 私钥
    static bool RSASignAction( char *str, QString &strSigned, const char *pri);

    // 验签  strData 原始字符串; strSigned 待验签字符串 ;strPubKey 公钥
    static bool RSAVerAction(QString strData,QString &strSigned,QString & strPubKey);
    /**< 测试 */
    static void test ();

};

#endif // RSA_H

源文件

#include "rsa.h"

// 转换为base64格式输出 
int Base64Encode(unsigned char *plaintext, size_t plainlen, char *ciphertext,size_t *cipherlen)
{
    if (!ciphertext)
    {
        *cipherlen = (plainlen + 2) / 3 * 4;
        return 0;
    }
    int nLen = EVP_EncodeBlock((unsigned char *)ciphertext, (const unsigned char *)plaintext,
                               (int)plainlen);
    if (nLen < 0)
    {
        return -2;
    }
    *cipherlen = nLen;
    return 0;
}

rsa::rsa()
{

}
bool rsa::MakeUpRsaKey (QString& strPubKey, QString& strPriKey)
{
     RSA *pRsa = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL);
     if ( !pRsa ){
         return false;
     }
     BIO *pPriBio = BIO_new(BIO_s_mem());
     PEM_write_bio_RSAPrivateKey(pPriBio, pRsa, NULL, NULL, 0, NULL, NULL);
     BIO *pPubBio = BIO_new(BIO_s_mem());
     PEM_write_bio_RSAPublicKey(pPubBio, pRsa);
     // 获取长度
     size_t nPriKeyLen = BIO_pending(pPriBio);
     size_t nPubKeyLen = BIO_pending(pPubBio);
     // 密钥对读取到字符串
     char* pPriKey = new char[nPriKeyLen];
     char* pPubKey = new char[nPubKeyLen];
     BIO_read(pPriBio, pPriKey, nPriKeyLen);
     BIO_read(pPubBio, pPubKey, nPubKeyLen);
     // 存储密钥对
     strPubKey = QByteArray(pPubKey, nPubKeyLen);
     strPriKey = QByteArray(pPriKey, nPriKeyLen);
     // 内存释放
     RSA_free(pRsa);
     BIO_free_all(pPriBio);
     BIO_free_all(pPubBio);
     delete pPriKey;
     delete pPubKey;
     return true;
}

/**
 * @brief rsa_pri_encrypt 私钥加密
 * @param strClearData 明文
 * @param strPriKey 私钥
 * @return 加密后数据(base64格式)
 */
QString rsa::rsa_pri_encrypt_base64 (const QString& strClearData, const QString& strPriKey)
{
    QByteArray priKeyArry = strPriKey.toUtf8();
    uchar* pPriKey = (uchar*)priKeyArry.data();
    BIO* pKeyBio = BIO_new_mem_buf(pPriKey, strPriKey.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* pEncryptBuf = new char[nLen];
    memset(pEncryptBuf, 0, nLen);
    QByteArray clearDataArry = strClearData.toUtf8();
    int nClearDataLen = clearDataArry.length();
    uchar* pClearData = (uchar*)clearDataArry.data();
    int nSize = RSA_private_encrypt(nClearDataLen,
                                    pClearData,
                                    (uchar*)pEncryptBuf,
                                    pRsa,
                                    RSA_PKCS1_PADDING);
    QString strEncryptData = "";
    if ( nSize >= 0 ){
         QByteArray arry(pEncryptBuf, nSize);
         strEncryptData = arry.toBase64();
    }
    // 释放内存
    delete pEncryptBuf;
    BIO_free_all(pKeyBio);
    RSA_free(pRsa);
    return strEncryptData;
}

/**
 * @brief rsa_pub_decrypt 公钥解密
 * @param strDecrypt 待解密数据(base64格式)
 * @param strPubKey 公钥
 * @return 明文
 */
QString rsa::rsa_pub_decrypt_base64(const QString& strDecryptData, const QString& strPubKey)
{
    QByteArray pubKeyArry = strPubKey.toUtf8();
    uchar* pPubKey = (uchar*)pubKeyArry.data();
    BIO* pKeyBio = BIO_new_mem_buf(pPubKey, strPubKey.length());
    if (pKeyBio == NULL){
        qDebug()<<"error 1";
        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);
        qDebug()<<"error 2";
        return "";
    }
    int nLen = RSA_size(pRsa);
    char* pClearBuf = new char[nLen];
    memset(pClearBuf, 0, nLen);
    //解密
    QByteArray decryptDataArry = strDecryptData.toUtf8();
    decryptDataArry = QByteArray::fromBase64(decryptDataArry);
    int nDecryptDataLen = decryptDataArry.length();
    uchar* pDecryptData = (uchar*)decryptDataArry.data();
    int nSize = RSA_public_decrypt(nDecryptDataLen,
                                   pDecryptData,
                                   (uchar*)pClearBuf,
                                   pRsa,
                                   RSA_PKCS1_PADDING);
    QString strClearData = "";
    if ( nSize >= 0 ){
        strClearData = QByteArray(pClearBuf, nSize);
    }

    // 释放内存
    delete pClearBuf;
    BIO_free_all(pKeyBio);
    RSA_free(pRsa);
    return strClearData;
}

/**
 * @brief rsa_pub_encrypt 公钥加密
 * @param strClearData 明文
 * @param strPubKey 私钥
 * @return 加密后数据(base64格式)
 */
QString rsa::rsa_pub_encrypt_base64 (const QString& strClearData, 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];
    memset(pEncryptBuf, 0, nLen);

    QByteArray clearDataArry = strClearData.toUtf8();
    int nClearDataLen = clearDataArry.length();
    uchar* pClearData = (uchar*)clearDataArry.data();
    int nSize = RSA_public_encrypt(nClearDataLen,
                                   pClearData,
                                   (uchar*)pEncryptBuf,
                                   pRsa,
                                   RSA_PKCS1_PADDING);
    QString strEncryptData = "";
    if ( nSize >= 0 ){
        QByteArray arry(pEncryptBuf, nSize);
        strEncryptData = arry.toBase64();
    }
    // 释放内存
    delete pEncryptBuf;
    BIO_free_all(pKeyBio);
    RSA_free(pRsa);
    return strEncryptData;
}

/**
 * @brief rsa_pri_decrypt 私钥解密
 * @param strDecrypt 待解密数据(base64格式)
 * @param strPriKey 私钥
 * @return 明文
 */
QString rsa::rsa_pri_decrypt_base64(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* pClearBuf = new char[nLen];
    memset(pClearBuf, 0, nLen);

    //解密
    QByteArray decryptDataArry = strDecryptData.toUtf8();
    decryptDataArry = QByteArray::fromBase64(decryptDataArry);
    int nDecryptDataLen = decryptDataArry.length();
    uchar* pDecryptData = (uchar*)decryptDataArry.data();
    int nSize = RSA_private_decrypt(nDecryptDataLen,
                                    pDecryptData,
                                    (uchar*)pClearBuf,
                                    pRsa,
                                    RSA_PKCS1_PADDING);
    QString strClearData = "";
    if ( nSize >= 0 ){
        strClearData = QByteArray(pClearBuf, nSize);
    }
    // 释放内存
    delete pClearBuf;
    BIO_free_all(pKeyBio);
    RSA_free(pRsa);
    return strClearData;
}

void rsa::test()
{
    /**< rsa private/public key 若从文件中拷贝出来,需要注意保存元先文件格式,即换行符需要带上,包括最后一行的换行符 */
    //QString strPriKey = "";
   // QString strPubKey = "";
    /**
     *  用代码生成的key与openssl命令生成的key区别:
     *  1、代码生成key,标题为 -----BEGIN RSA PUBLIC KEY-----,openssl命令生成key, 标题为 -----BEGIN PUBLIC KEY-----
     *  2、获取RSA函数不同,代码生成key,用PEM_read_bio_RSAPublicKey,openssl命令生成key,用PEM_read_bio_RSA_PUBKEY
    */
    //MakeUpRsaKey(strPubKey, strPriKey);
    //qDebug() << strPubKey << endl;
    //qDebug() << strPriKey << endl;
    /*strPubKey = QString("-----BEGIN PUBLIC KEY-----\n")+
            QString("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbXcFx8TIEnRjS9H+KxapUBI6r\n") +
            QString("QO8ZeeZKDpa1V/lUg7FsUOdhfjze8YkL2F1et0zSjK7YeQPjWO8NDg7/TTLfpW27\n")+
            QString("krhkreYFQ9Y4vHrCKhjc3DD+Yzy9wyKKn5O9M9qU0Kzu8ads/mrPe82/xoo/XDv2\n") +
            QString("eTR755MEi1BO+S1RLQIDAQAB\n")+
            QString("-----END PUBLIC KEY-----");

    strPriKey = QString("-----BEGIN PRIVATE KEY-----\n")+
            QString("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJtdwXHxMgSdGNL0\n") +
            QString("f4rFqlQEjqtA7xl55koOlrVX+VSDsWxQ52F+PN7xiQvYXV63TNKMrth5A+NY7w0O\n") +
            QString("Dv9NMt+lbbuSuGSt5gVD1ji8esIqGNzcMP5jPL3DIoqfk70z2pTQrO7xp2z+as97\n") +
            QString("zb/Gij9cO/Z5NHvnkwSLUE75LVEtAgMBAAECgYBkwqY9hkaBFX1O+wBoeI9hk98P\n") +
            QString("E7q9VABVUSbOjzKFbC855zJYWS2TDSRrSTQsxEYPWuveOoWaAUhvuAlj66YswIL6\n") +
            QString("BRgA20eoDr34w+1GABXbFSrP2L1rR2v0qEdiSPsACI0aAmZGO4eq+Fns+EuJ0KSg\n") +
            QString("FIZmv3rJV7Nhd9aTQQJBAMmpvcCjxVLfTfiT52j6FDTpAMmd5e832EUEWdzAIzh7\n") +
            QString("Z57vsmR7eGbp+9kiRl3eZMOPg2wdfkXvHUrmQK0F/p0CQQDFOpCs75lIVufTZKDU\n") +
            QString("7tMQXr4Tzc8EJPaeBuSDXey5okek+ntq55C3xo8nEgDtaVP6mcLqpZR/s+6PjChb\n") +
            QString("rk/RAkBzQ7z8pd78Xjx/z3Iec4onL+LOWpz5XW8VC8adQYkgGJECrDjH7DbGhAj6\n") +
            QString("c/fKYXowuQ/CNR1etayFihP/kYSVAkB0sxSL3zG5hgKiKHapx66Hjye1HCAT+bMb\n") +
            QString("CkUIHflGVelCixufw+jzdL+bhKGb2KjiLT0SDmtxrIvJ0ErJBLkhAkEAj8Yh3H+W\n") +
            QString("OWauml/oVqNTbCKttV6irPYVUJkcJnnByjWxVP2I7hmJNuxNAKsNjR204IMsMaWh\n") +
            QString("qbByj4ywB5LieQ==\n")+
            QString("-----END PRIVATE KEY-----");*/


   /* qDebug() << "useing publicKey to Encrypt and privateKey Decrypt:";
    QString strClear = "hello334344554 WORLD12W2WDWDEDWDD";
    qDebug() << "after publicKey Encrypt:";
    QString strEncryptData = rsa_pub_encrypt_base64 (strClear, strPubKey);
    qDebug() << strEncryptData;
    qDebug()<<  "after privateKey Decrypt:";
    QString strClearData = rsa_pri_decrypt_base64 (strEncryptData, strPriKey);
    qDebug() << strClearData;*/

    // 现在进行签名测试,使用私钥签名,公钥验签
    QString priKey = QString("-----BEGIN PRIVATE KEY-----\n")+
            QString("MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAJQOMmftEDgwvnM3\n") +
            QString("PKWbvF+xvSGLVaJYySSQtmKczEE2ufYR2LM2qwsZhBUwzW+ssKGVrCsjmmI5G4oF\n") +
            QString("gcVsa3uA221c6oDaERvQYrFNN9KaLNrIdEA1Nh0MTAg5M6AK2wTHnPH5DGrVXtGs\n") +
            QString("k6ZLTuKUjpR8iWMMc+0C5ApG3ssLAgMBAAECgYAEiLbEdf8UKXH7p0plK/LF33SS\n") +
            QString("TWkO8rceNoxPUsvyh1GElqFTQ65TRbHE0FzKObijCilenNWCgos0W9zQhfR4pLkJ\n") +
            QString("jZyv+W4xJ3qAH7drzcd2MgBP1v91gJK6VPjD+J0pNACF1xGLsFBZmWIbFATDU38z\n") +
            QString("3SbTPVS15oPXgDdEwQJBAOF2v+skafKdtKmLgy3Hna+iA+uNNUZ7q8bQyjY4nviV\n") +
            QString("FRL3MBgugIpUYaiiCzhl8BZftoB6pg0DCBOlQxONgiECQQCoG43bGjM0uh7e8cMT\n") +
            QString("45OJDruii7wQnpJuZZH67qOGtnZA/coYDGArqFwmrQz2nQJGwePvNt4kT3Ibighf\n") +
            QString("ev+rAkEAtuXKEkpb2ACvCcqvA3gnJs7bNz45tY+lbYb6Qrnz29u0WMpFLZirlYuW\n") +
            QString("HWI2j+3BsaS7O8ZC5dNLvgQWQcpNgQJBAJwm3CIFuELmD/7ve1FiN408TjayrcKS\n") +
            QString("SVqapnr8aJGds0Kze6HS/RIQlWinnj8FoTOwrtVplfcMhOXn1dc7HXkCQQCRu9UN\n") +
            QString("4mMrQLLg7S88fbjxsy7+cuELxBNrix3GU8F6EAtWWq2e1EaUu0VVtRq7f/IKPdKD\n") +
            QString("uEBxsPfr/EXy6yDw\n")+
            QString("-----END PRIVATE KEY-----");

    QString pbKey = QString("-----BEGIN PUBLIC KEY-----\n")+
           QString("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUDjJn7RA4ML5zNzylm7xfsb0h\n") +
           QString("i1WiWMkkkLZinMxBNrn2EdizNqsLGYQVMM1vrLChlawrI5piORuKBYHFbGt7gNtt\n")+
           QString("XOqA2hEb0GKxTTfSmizayHRANTYdDEwIOTOgCtsEx5zx+Qxq1V7RrJOmS07ilI6U\n") +
           QString("fIljDHPtAuQKRt7LCwIDAQAB\n")+
           QString("-----END PUBLIC KEY-----");

    QString aaa = "SZHAILEI88123456&111122334";

    QString ret="";
   rsa::RSASignAction(aaa,ret,priKey);

    qDebug()<<"after =========> "<<ret;

   bool flag = rsa::RSAVerAction(aaa,ret,pbKey);
   if(flag){
       qDebug()<<"@@@@@@@@@@ success !";
   }else{
       qDebug()<<"@@@@@@@@@ failed !";
   }
}


bool rsa::RSASignAction(QString strData, QString &strSigned,QString &strPriKey)
{

    qDebug()<<"now rsa sign";
    QByteArray clearDataArry = strData.toUtf8();
    int len = clearDataArry.length();
    QByteArray priKeyArry = strPriKey.toUtf8();
    uchar* pPriKey = (uchar*)priKeyArry.data();
    BIO* pKeyBio = BIO_new_mem_buf(pPriKey, strPriKey.length());
    if (pKeyBio == NULL){

        return false;
    }
    RSA* prsa = NULL;
    prsa = PEM_read_bio_RSAPrivateKey(pKeyBio, &prsa, NULL, NULL);
    if ( prsa == NULL ){
        BIO_free_all(pKeyBio);
        return false;
    }

    unsigned char szTmp[1024] = {0};
    SHA256((const unsigned char*)clearDataArry.data(),len,szTmp);
    int nlen = 0;
    unsigned int nlenRet = 0;
    char szTmp1[1024] = {0};
    nlen  = RSA_sign(NID_sha256,szTmp,SHA256_DIGEST_LENGTH,(unsigned char*)szTmp1,&nlenRet,prsa);
    if(nlen!=1){
        RSA_free(prsa);
        BIO_free_all(pKeyBio);
        return false;
    }
    QByteArray  arry = QByteArray(szTmp1);
    strSigned = QString(arry.toBase64());
    BIO_free_all(pKeyBio);
    RSA_free(prsa);
    return true;
}

bool rsa::RSAVerAction( char *str, QString &strSigned, const char *pri)
{
    int  len = strlen(str);
    BIO* pKeyBio = BIO_new_mem_buf(pri, strlen(pri));
    if (pKeyBio == NULL){

        return false;
    }
    RSA* prsa = NULL;
    prsa = PEM_read_bio_RSAPrivateKey(pKeyBio, &prsa, NULL, NULL);
    if ( prsa == NULL ){
        BIO_free_all(pKeyBio);
        return false;
    }
    unsigned char szTmp[1024] = {0};
    SHA256((const unsigned char*)str,len,szTmp);
    int nlen = 0;
    unsigned int nlenRet = 0;
   unsigned char szTmp1[1024] = {0};
    nlen  = RSA_sign(NID_sha256,szTmp,SHA256_DIGEST_LENGTH,szTmp1,&nlenRet,prsa);
    if(nlen!=1){
        RSA_free(prsa);
        BIO_free_all(pKeyBio);
        return false;
    }
    size_t plainlen = 0;
    uint8_t plaintext[1024]={0};
    Base64Encode(szTmp1,nlenRet,(char*)plaintext,&plainlen);
    strSigned = QString("%1").arg((char*)plaintext);
    BIO_free_all(pKeyBio);
    RSA_free(prsa);
    return true;
}



你可能感兴趣的:(QT,C++,c++,qt)