rsa加密(linux C语言)

demo_rsa.cpp文件名(准确性不是100%,原因未找到)
//demo_rsa.cpp
//linux环境,先安装openssl库
//g++ demo_rsa.cpp -lcrypto
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <string.h> 
#include <iostream>
#include <string>
#include <cstring>
#include <cassert>
#include <stdio.h>
#include <unistd.h>

using namespace std;
 
//加密
std::string EncodeRSAKeyFile( const std::string& strPemFileName, const std::string& strData )
{
    if (strPemFileName.empty() || strData.empty())
    {
        assert(false);
        return "";
    }
    FILE* hPubKeyFile = fopen(strPemFileName.c_str(), "rb");
    if( hPubKeyFile == NULL )
    {
        assert(false);
        return ""; 
    }
    std::string strRet;
    RSA* pRSAPublicKey = RSA_new();
    if(PEM_read_RSA_PUBKEY(hPubKeyFile, &pRSAPublicKey, 0, 0) == NULL)
    {
        assert(false);
        return "";
    }
 
    int nLen = RSA_size(pRSAPublicKey);
    char* pEncode = new char[nLen + 1];
    int ret = RSA_public_encrypt(strData.length(), (const unsigned char*)strData.c_str(), (unsigned char*)pEncode, pRSAPublicKey, RSA_PKCS1_PADDING);
    if (ret >= 0)
    {
        strRet = std::string(pEncode, ret);
    }
    delete[] pEncode;
    RSA_free(pRSAPublicKey);
    fclose(hPubKeyFile);
    CRYPTO_cleanup_all_ex_data(); 
    return strRet;
}
 
//解密
char *DecodeRSAKeyFile( const char *strPemFileName, const char * strData, char *outValue)
{
    if (!strPemFileName || !strData)
    {
        cout<<"0#######: " <<endl << endl;

        //return "";
    }
    FILE* hPriKeyFile = fopen(strPemFileName,"rb");
    if( hPriKeyFile == NULL )
    {
        cout<<"1#######: " <<endl << endl;
        //return "";
    }

    RSA* pRSAPriKey = RSA_new();
    if(PEM_read_RSAPrivateKey(hPriKeyFile, &pRSAPriKey, 0, 0) == NULL)
    {
        cout<<"2#######: " <<endl << endl;
        //return "";
    }
    int nLen = RSA_size(pRSAPriKey);
    //char* pDecode = new char[nLen+1];
    char* pDecode = (char *)malloc(nLen+1);

    
    int ret = RSA_private_decrypt(strlen(strData), (const unsigned char*)strData, (unsigned char*)pDecode, pRSAPriKey, RSA_PKCS1_PADDING);
    if(ret >= 0)
    {

        cout<<"pDecode: " << pDecode << endl << endl;
        //strRet = std::string((char*)pDecode, ret);
        strcpy(outValue, pDecode);
    }

    
    //delete [] pDecode;
    free(pDecode);
    RSA_free(pRSAPriKey);
    fclose(hPriKeyFile);
    CRYPTO_cleanup_all_ex_data(); 
    //return strRet;
}

string base64Encode(const /*unsigned*/ char* Data,int DataByte)
{
        //编码表
        const char EncodeTable[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        //返回值
        string strEncode;
        unsigned char Tmp[4]={0};
        int LineLength=0;
        for(int i=0;i<(int)(DataByte / 3);i++)
        {
            Tmp[1] = *Data++;
            Tmp[2] = *Data++;
            Tmp[3] = *Data++;
            strEncode+= EncodeTable[Tmp[1] >> 2];
            strEncode+= EncodeTable[((Tmp[1] << 4) | (Tmp[2] >> 4)) & 0x3F];
            strEncode+= EncodeTable[((Tmp[2] << 2) | (Tmp[3] >> 6)) & 0x3F];
            strEncode+= EncodeTable[Tmp[3] & 0x3F];
            if(LineLength+=4,LineLength==76) {strEncode+="\r\n";LineLength=0;}
        }
        //对剩余数据进行编码
        int Mod=DataByte % 3;
        if(Mod==1)
        {
            Tmp[1] = *Data++;
            strEncode+= EncodeTable[(Tmp[1] & 0xFC) >> 2];
            strEncode+= EncodeTable[((Tmp[1] & 0x03) << 4)];
            strEncode+= "==";
        }
        else if(Mod==2)
        {
            Tmp[1] = *Data++;
            Tmp[2] = *Data++;
            strEncode+= EncodeTable[(Tmp[1] & 0xFC) >> 2];
            strEncode+= EncodeTable[((Tmp[1] & 0x03) << 4) | ((Tmp[2] & 0xF0) >> 4)];
            strEncode+= EncodeTable[((Tmp[2] & 0x0F) << 2)];
            strEncode+= "=";
        }
        
        return strEncode;
}

string base64Decode(const char* Data,int DataByte,int& OutByte)
{
        //解码表
        const char DecodeTable[] =
        {
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            62, // '+'
            0, 0, 0,
            63, // '/'
            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
            0, 0, 0, 0, 0, 0, 0,
            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
            13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
            0, 0, 0, 0, 0, 0,
            26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
            39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
        };
        //返回值
        string strDecode;
        int nValue;
        int i= 0;
        while (i < DataByte)
        {
            if (*Data != '\r' && *Data!='\n')
            {
                nValue = DecodeTable[*Data++] << 18;
                nValue += DecodeTable[*Data++] << 12;
                strDecode+=(nValue & 0x00FF0000) >> 16;
                OutByte++;
                if (*Data != '=')
                {
                    nValue += DecodeTable[*Data++] << 6;
                    strDecode+=(nValue & 0x0000FF00) >> 8;
                    OutByte++;
                    if (*Data != '=')
                    {
                        nValue += DecodeTable[*Data++];
                        strDecode+=nValue & 0x000000FF;
                        OutByte++;
                    }
                }
                i += 4;
            }
            else// 回车换行,跳过
            {
                Data++;
                i++;
            }
         }
        return strDecode;
}

int main()
{
#if 1
    //原文
    int OutByte = 0, i = 0;
    //string passwd = "n6g0I49x";

    const char *passwd1 = "1ryueaksdjlgjaeogjao;rgj;ioqeg";
    string passwd(passwd1);


    const char *value1 = NULL;
    const char *value2 = NULL;

    //rsa通过公钥加密,会生成乱码
    string tmp1 = EncodeRSAKeyFile("public.pem", passwd);
    cout<<"tmp1: " << tmp1 << endl << endl;

    value1 = tmp1.c_str();
    //value1 = tmp1.data();
    
    cout<<"value1: " << value1 << endl << endl;

    /*
    if(strlen(value1) < 128 ){
        continue;
    }*/
    
    //将乱码,进行base64转码
    string tmp2 = base64Encode(value1, strlen(value1));
    cout<<"tmp2: " << tmp2 <<"             len: " << strlen(value1) << endl << endl;

    //存放到数据库

    //从数据库获取密码的base64


    value2 = tmp2.c_str();
    cout<<"value2: " << value2 << endl << endl;
 #endif
    //int OutByte = 0, i = 0;
    char outVa[256];
    //从数据库拿出来base64的密码就是char*类型,解码base64
    //const char *value2 = "n6g0I49x";
    //const char *value2 = "DQ0GLBGZ3G/DSrxpgZFdlMVzehPBw23HdPdRcaNTvk1NlEzBLyrburlinkqSyj9UZHwMgDuuiHobOTAx+jLqR54REHWfwN5rSYaykD05UGP/0gi4kaGx/Eb6+h77sZxp7ppvSEEA1tHJEmKgdiP6SuBvh06qiPPTaRwcqRAoR6E=";
    string tmp3 = base64Decode(value2, strlen(value2), OutByte);
    cout<<"tmp3: " << tmp3 << endl << endl;
    const char *tmp3_3 = tmp3.c_str();
    cout<<"tmp3_3: " << tmp3_3 << endl << endl;
    //解密rsa
    DecodeRSAKeyFile("private.pem", tmp3_3, outVa);
    cout<<"tmp4: " << outVa << endl << endl;

    return 0;  
}


private.pem  私钥文件

-----BEGIN PRIVATE KEY-----
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMOKAGw1bJwgPS8i
gGvuK57jxjsDYKegPdzLAWWQZiThPqQ58bjHK2ZRvad5B3G043bpssgrpfpkdWBj
XlCW7ELZdgc0iKCWKjKHyzq7gmsgAXXayTTl84nZxSUCeJ0+8G4075eOS0ns9GU3
V9LhD6o1YUberEtIQfxmfK0zm92FAgMBAAECgYEAwAJpO9iSGBVIP1qfxFwRlWqR
Iy3D4ZZmaMMnUfYjdx9/hYAorotVQJoPo74i4zL/EauWFR1XVLME12t8F6K7x4l7
OWGQVc509IMcayTuF/ibNPcUy2yZcsWwgde76VvNnjwOUpW6UuZFA08uNbAEpr5r
4H/Cw0ZMIJAeLltRogECQQDlfGAYjhL87HclObX/+jZ9fVzTPguuqVHMCYH0Kv/L
Mb62gy7UHF8se8rOIRSLIy3X3wJtYhVx5l1WjTqnPphFAkEA2iGQhuyf6wifMln1
9PYhRm28NKvDPQvtEFp00pgsnQhXiqhWy1Uw138AX83G0Nm4+EIngAT1DCaXWhcX
HK+kQQJBAK4LbjYxSmVYUeSBqG7DLaBu+3+ahvGoqMi+TTkJg4Zv69wwEcv82JG8
MUuz+wirXZFjKUwcH3eK5y9FXT6KUqECQFfzuqu8k0qYgmAyB8tKxuX37zAppaJi
waabYolblHmI2ItvDvgTlIr/iW4XsbeaYkuvmO+0j/3jPZm0v7vwUkECQQDKa2pK
pRYOlv6NizApzGhTSVDuV5ifncC/hOQRot9vw+eykuNaHOUyNnzh9arBuUhRtwga
HKwW1fO0hVvU4PEd
-----END PRIVATE KEY-----

公钥文件 public.pem

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDigBsNWycID0vIoBr7iue48Y7
A2CnoD3cywFlkGYk4T6kOfG4xytmUb2neQdxtON26bLIK6X6ZHVgY15QluxC2XYH
NIiglioyh8s6u4JrIAF12sk05fOJ2cUlAnidPvBuNO+XjktJ7PRlN1fS4Q+qNWFG
3qxLSEH8ZnytM5vdhQIDAQAB
-----END PUBLIC KEY-----



(同一个文件夹下,放这三个文件, 编译g++ demo_rsa.cpp -lcrypto)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值