rsa des加密解密,与c++混合使用. c++ 篇

2 篇文章 0 订阅

c++ 下des的运用

通过openssl 进行加密解密

myDes.h

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/des.h>
#include <iostream>
#include <vector>
using namespace std;

typedef enum{
    CBC=1,
}desmode_t;

typedef enum{
   PAD_PKCS5=1,
}mypadmode_t;


class my_Des
{
public:
    my_Des(std::string userkey,desmode_t userdesmode=CBC, std::string IV=NULL,mypadmode_t padmode=PAD_PKCS5);
    std::string decrypt(const std::string &cipherText,mypadmode_t mypadmode);
    std::string decrypt(const std::string &cipherText);
    std::string des_cbc_pkcs5_decrypt(char *cipherText, int datalen, const std::string &key);
    std::string des_cbc_pkcs5_encrypt(char *cipherText, int datalen, const std::string &key);
    std::string des_cbc_pkcs5_encrypt(const std::string &clearText, const std::string &key);
private:
    std::string padFUN(const std::string &cipherText,mypadmode_t mypadmode);
    std::string des_cbc_pkcs5_decrypt(const std::string &cipherText, const std::string &key);

private:
   mypadmode_t mypadmode;
   desmode_t desmode;
   std::string key;
   std::string my_iv;
};

myDes.cpp

#include "myDes.h"

my_Des::my_Des(std::string userkey,desmode_t userdesmode, std::string IV,mypadmode_t padmode)
{
   key=userkey;
   desmode=userdesmode;
   mypadmode=padmode;
   my_iv=IV;
}

//解密 cbc pkcs5padding 自己实现  //zeropadding / pkcs7padding 跟 pkcs5padding是一样的
std::string my_Des::des_cbc_pkcs5_decrypt(const std::string &cipherText, const std::string &key)
{

   // static unsigned char cbc_iv[8] = {'m', 'H', 'A', 'x', 's', 'L', 'Y', 'z'};
    static unsigned char cbc_iv[8];
    memcpy(cbc_iv,my_iv.data(),sizeof (cbc_iv));
    //初始化IV向量
    std::string clearText;
    DES_cblock keyEncrypt, ivec;
    memset(keyEncrypt, 0, 8);

    if (key.length() <= 8)
        memcpy(keyEncrypt, key.c_str(), key.length());
    else
        memcpy(keyEncrypt, key.c_str(), 8);

    DES_key_schedule keySchedule;  //密钥表
    DES_set_key_unchecked(&keyEncrypt, &keySchedule);   //设置密钥,且不检测密钥奇偶性
    memcpy(ivec, cbc_iv, sizeof(cbc_iv));

    // 循环解密,每8字节一次
    const_DES_cblock inputText;
    DES_cblock outputText;
    std::vector<unsigned char> vecCleartext;
    unsigned char tmp[8];
    for (unsigned int i = 0; i < cipherText.length() / 8; i++)
    {
        memcpy(inputText, cipherText.c_str() + i * 8, 8);
        DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_DECRYPT);  //解密
        memcpy(tmp, outputText, 8);
        for (int j = 0; j < 8; j++)
            vecCleartext.push_back(tmp[j]);
        //重置ivec
        //memcpy(ivec, outputText, 8);  //解密过程不需要用前一块的结果作为下一块的IV
    }

    unsigned int mod=clearText.length() % 8;
    if (mod != 0)
    {
        unsigned int tmp1 = clearText.length() / 8 * 8;
        unsigned int tmp2 = clearText.length() - tmp1;
        memset(inputText,0, static_cast<size_t>(tmp2));
        memcpy(inputText, cipherText.c_str() + tmp1, tmp2);
        DES_ncbc_encrypt(inputText, outputText, static_cast<long>(tmp2), &keySchedule, &ivec, DES_DECRYPT);  //解密
        memcpy(tmp, outputText, tmp2);

        for (unsigned int j = 0; j < mod; j++)
            vecCleartext.push_back(tmp[j]);
    }
    clearText.clear();
    clearText.assign(vecCleartext.begin(),vecCleartext.end());

    // 返回值去除末尾的填充值
    unsigned int retlen=clearText.length();
    unsigned int modlen=static_cast<unsigned int>(clearText[retlen-1]);

   // for(char i=0;i<retlen;i++)
     //   clearText.pop_back();
   // clearText.erase(retlen-modlen,retlen);

    return clearText;
}
//这里有一个char * 和 string 两个版本, string 为网上大神的版本,char * 为自己改进的,因为字符串中遇到'\0'就截止。但是加密字串难免回产生'\0' 所以 以char * 处理更好
std::string my_Des::des_cbc_pkcs5_encrypt(char *cipherText, int datalen, const std::string &key)
{
   // static unsigned char cbc_iv[8] = {'j', 'k', 't', '1', '2', '3', '4', '5'};
    static unsigned char cbc_iv[8];
    memcpy(cbc_iv,my_iv.data(),sizeof (cbc_iv));
    //初始化IV向量
    std::string strCipherText;
    DES_cblock keyEncrypt, ivec;
    memset(keyEncrypt, 0, 8);

    if (key.length() <= 8)
        memcpy(keyEncrypt, key.c_str(), key.length());
    else
        memcpy(keyEncrypt, key.c_str(), 8);

    DES_key_schedule keySchedule;  //密钥表
    DES_set_key_unchecked(&keyEncrypt, &keySchedule);   //设置密钥,且不检测密钥奇偶性

    memcpy(ivec, cbc_iv, sizeof(cbc_iv));

     // 循环加密,每8字节一次
    const_DES_cblock inputText;
    DES_cblock outputText;
    std::vector<unsigned char> vecCiphertext;
    unsigned char tmp[8];

    for (int i = 0; i < datalen / 8; i++)
    {
        memcpy(inputText,cipherText + i * 8, 8);
        DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密
        memcpy(tmp, outputText, 8);

        for (int j = 0; j < 8; j++)
            vecCiphertext.push_back(tmp[j]);

        //重置ivec
        memcpy(ivec, outputText, 8);
    }

    if (datalen% 8 != 0)
    {
        int tmp1 =datalen / 8 * 8;
        int tmp2 = datalen - tmp1;
        memset(inputText,(8-tmp2), 8);
        memcpy(inputText, cipherText + tmp1, tmp2);
    }
    else
    {
        memset(inputText,8, 8);
    }
    // 加密函数
    DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密
    memcpy(tmp, outputText, 8);

    for (int j = 0; j < 8; j++)
        vecCiphertext.push_back(tmp[j]);

    strCipherText.clear();
    strCipherText.assign(vecCiphertext.begin(), vecCiphertext.end());
    return strCipherText;
}


std::string my_Des::des_cbc_pkcs5_encrypt(const std::string &clearText, const std::string &key)
{
    static unsigned char cbc_iv[8];
    memcpy(cbc_iv,my_iv.data(),sizeof (cbc_iv));
    //初始化IV向量
    std::string strCipherText;
    DES_cblock keyEncrypt, ivec;
    memset(keyEncrypt, 0, 8);

    if (key.length() <= 8)
        memcpy(keyEncrypt, key.c_str(), key.length());
    else
        memcpy(keyEncrypt, key.c_str(), 8);

    DES_key_schedule keySchedule;  //密钥表
    DES_set_key_unchecked(&keyEncrypt, &keySchedule);   //设置密钥,且不检测密钥奇偶性

    memcpy(ivec, cbc_iv, sizeof(cbc_iv));

     // 循环加密,每8字节一次
    const_DES_cblock inputText;
    DES_cblock outputText;
    std::vector<unsigned char> vecCiphertext;
    unsigned char tmp[8];

    for (int i = 0; i < clearText.length() / 8; i++)
    {
        memcpy(inputText, clearText.c_str() + i * 8, 8);
        DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密
        memcpy(tmp, outputText, 8);

        for (int j = 0; j < 8; j++)
            vecCiphertext.push_back(tmp[j]);

        //重置ivec
        memcpy(ivec, outputText, 8);
    }

    if (clearText.length() % 8 != 0)
    {
        int tmp1 = clearText.length() / 8 * 8;
        int tmp2 = clearText.length() - tmp1;
        memset(inputText,(8-tmp2), 8);
        memcpy(inputText, clearText.c_str() + tmp1, tmp2);
    }
    else
    {
        memset(inputText,8, 8);
    }
    // 加密函数
    DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_ENCRYPT);  //加密
    memcpy(tmp, outputText, 8);

    for (int j = 0; j < 8; j++)
        vecCiphertext.push_back(tmp[j]);

    strCipherText.clear();
    strCipherText.assign(vecCiphertext.begin(), vecCiphertext.end());
    return strCipherText;
}

std::string my_Des::des_cbc_pkcs5_decrypt(char *cipherText, int datalen, const std::string &key)
{

   // static unsigned char cbc_iv[8] = {'m', 'H', 'A', 'x', 's', 'L', 'Y', 'z'};
    static unsigned char cbc_iv[8];
    memcpy(cbc_iv,my_iv.data(),sizeof (cbc_iv));
    //初始化IV向量
    std::string clearText;
    DES_cblock keyEncrypt, ivec;
    memset(keyEncrypt, 0, 8);

    if (key.length() <= 8)
        memcpy(keyEncrypt, key.c_str(), key.length());
    else
        memcpy(keyEncrypt, key.c_str(), 8);

    DES_key_schedule keySchedule;  //密钥表
    DES_set_key_unchecked(&keyEncrypt, &keySchedule);   //设置密钥,且不检测密钥奇偶性

    memcpy(ivec, cbc_iv, sizeof(cbc_iv));

    // 循环解密,每8字节一次
    const_DES_cblock inputText;
    DES_cblock outputText;
    std::vector<unsigned char> vecCleartext;
    unsigned char tmp[8];
    for (unsigned int i = 0; i < (datalen)/ 8; i++)
    {
        memcpy(inputText, cipherText + i * 8, 8);
        DES_ncbc_encrypt(inputText, outputText, 8, &keySchedule, &ivec, DES_DECRYPT);  //解密
        memcpy(tmp, outputText, 8);
        for (int j = 0; j < 8; j++)
            vecCleartext.push_back(tmp[j]);
        //重置ivec
        //memcpy(ivec, outputText, 8);  //解密过程不需要用前一块的结果作为下一块的IV
    }

    unsigned int mod=(datalen) % 8;
    if (mod != 0)
    {
        unsigned int tmp1 = clearText.length() / 8 * 8;
        unsigned int tmp2 = clearText.length() - tmp1;
        memset(inputText,0, static_cast<size_t>(tmp2));
        memcpy(inputText, cipherText + tmp1, tmp2);
        DES_ncbc_encrypt(inputText, outputText, static_cast<long>(tmp2), &keySchedule, &ivec, DES_DECRYPT);  //解密
        memcpy(tmp, outputText, tmp2);

        for (unsigned int j = 0; j < mod; j++)
            vecCleartext.push_back(tmp[j]);
    }
    clearText.clear();
    clearText.assign(vecCleartext.begin(),vecCleartext.end());

    // 返回值去除末尾的填充值
    unsigned int retlen=clearText.length();
    unsigned int modlen=static_cast<unsigned int>(clearText[retlen-1]);
   if(modlen<=8&&modlen>0)
   clearText.erase(retlen-modlen,retlen);

    return clearText;
}



std::string my_Des::decrypt(const std::string &cipherText,mypadmode_t mypadmode)
{
    switch (desmode) {
    case CBC:
        return padFUN(cipherText,mypadmode);

    }
    return  "";
}
std::string my_Des::decrypt(const std::string &cipherText)
{
    switch (desmode) {
    case CBC:
        return padFUN(cipherText,mypadmode);

    }
    return  "";
}

std::string my_Des::padFUN(const std::string &cipherText,mypadmode_t mypadmode)
{
    switch (mypadmode) {
    case PAD_PKCS5:
        return des_cbc_pkcs5_decrypt(cipherText,key);
    }
    return  "";
}

 rsa

#ifndef RSA_CLC_H
#define RSA_CLC_H

#include<stdio.h>
#include <fstream>
#include <iostream>
#include <string>
#include <QString>

#include <openssl/rsa.h>
#include<openssl/pem.h>
#include<openssl/err.h>
#include <openssl/bio.h>

//服务端公钥用于本地加密
const static char* server_pulicKey ="-----BEGIN RSA PUBLIC KEY-----\n"
"MIGJAoGBAKmV1KA9fjRrySfFbgozIDD0n19rL1pEUmM7wdho5qjl2w+wMlpxlqeO\n"
"YdbdMwtufbOekFQ4IcffORQfIynBpPeR12F5gQkC0sG1O8HkKdiDS88gcpVVKX1D\n"
"O77gW9p45Na5ZvajSYMo+4SIQeGWn5y8rCUfNfi3Vh/HeterMiHNAgMBAAE=\n"
"-----END RSA PUBLIC KEY-----";

//客户端私钥用于服务端消息解码
const static char* clientPrivateKey ='-----BEGIN RSA PRIVATE KEY-----\n"
        "MIICYQIBAAKBgQCSgVkZKHBVA/Fwdio4N2H1tjXTuwUW1ep9Vdzb3alBGJY575i2\n"
        "N4mVxjvgCTyZjnj0s9QCA+I7mvFpKShTglHHdfEOvO+7T/p246Iq9VGfwstYfdTE\n"
        "CNMiMzX1HdEfcZccEe65IJc8OfeoDHVPHvaGkxfU00kJA/rcdswJOn9hvQIDAQAB\n"
        "AoGAMRs4ES2z0Vs7/1UsO6GcrS6BBlJGl2vmaFJycCPxSoeCOzMrPdCJxnEmuqZ9\n"
        "8H6H3oW0R2Sj3RTHXFdWFi+Xg9PYOEiNg2/HrcvPBG0+/abreDpvIV3Xj6eqEK8i\n"
        "WCS0aQqfehW+QIfITdU4jRI1XjDdbHDAHY+7/ZsKdtyq0cECRQC4aWst/K7N0GMZ\n"
        "DTCx1KJNGTzII8fzPiCvkEaT/22UY/GH9muDVyXDgThwez3c+Wtax+TmuScOe06R\n"
        "0J86bj8X/kIATQI9AMtg1TGuLSlr58PuSfZLe7psBsv1UBfaXde43mtte1jaVpyF\n"
        "6i9Tprw4S+Y7hUqfUxbE6QL6anEpIyQfMQJFALRrPtcRHhxyQmHiC8AP3nI7vMG6\n"
        "cAdEw0nAh6yH/DdvyIBS0EEBZArwQ72YdZ/ZzfRVGVe50cJTVT1HtGDAN65LrVsJ\n"
        "AjxmhoQzLUkbDoih3yht/xN6oSaz/xDHVY/lRg7qPSDnY/oxodiyzwrI6+BnSi4h\n"
        "tjveyJlmpPKv5TsP5KECRQCnQ4/U07F91Vr8X33x1LlT4h66SRZm+PRodaNw0gIS\n"
        "Nps6pDX5CrA0FnLypO878JDTL0q/0mUx5otsfJo3IGF0jCaywQ==\n"
        "-----END RSA PRIVATE KEY-----\n";


using namespace std;
class Rsa_CLC
{
public:
    Rsa_CLC();
    QString rcvFromServer(string data);
    std::string sendToServer(QString data);
private:
    std::string Server_publicKey_jiami(string data);
    std::string Client_privateKey_jiemi(string data);
};

#endif // RSA_CLC_H

Rsa_CLC.cpp

#include "Rsa_CLC.h"

Rsa_CLC::Rsa_CLC()
{

}
std::string Rsa_CLC::Client_privateKey_jiemi(string data)
{
    OpenSSL_add_all_algorithms();
    BIO* bp = BIO_new( BIO_s_mem() );
    BIO_puts(bp, clientPrivateKey);

    RSA* rsaK;
    rsaK = PEM_read_bio_RSAPrivateKey( bp, NULL, NULL, NULL );
    if (NULL == rsaK) {
        perror("read key file fail!");
    }else{
        //printf("read success!\n");
    }

    int nLen = RSA_size(rsaK);
    char *pEncode = new char[nLen + 1];
    int ret = RSA_private_decrypt(data.length(),(const unsigned char*)data.c_str(),(unsigned char *)pEncode,rsaK,RSA_PKCS1_PADDING);
    std::string strRet;
    if (ret >= 0) {
        strRet = std::string(pEncode, ret);
    }

    delete[] pEncode;
    CRYPTO_cleanup_all_ex_data();
    BIO_free_all( bp );
    RSA_free(rsaK);
    return strRet;
}


std::string Rsa_CLC::Server_publicKey_jiami(string data)
{
    OpenSSL_add_all_algorithms();
    BIO* bp = BIO_new( BIO_s_mem() );
    BIO_puts(bp,server_pulicKey);
    RSA* rsaK = PEM_read_bio_RSAPublicKey( bp,NULL,NULL,NULL);
    if (NULL == rsaK) {
        return "";
    }
    int nLen = RSA_size(rsaK);
    char *pEncode = new char[nLen + 1];
    int ret = RSA_public_encrypt(data.length(),(const unsigned char*)data.c_str(),
        (unsigned char *)pEncode,rsaK,RSA_PKCS1_PADDING);
    std::string strRet;
    if (ret >= 0) {
        strRet = std::string(pEncode, ret);
    }
    delete[] pEncode;
    CRYPTO_cleanup_all_ex_data();
    BIO_free_all( bp );
    RSA_free(rsaK);
    return strRet;
}



QString Rsa_CLC::rcvFromServer(string data)
{
   std::string rcvstr=Client_privateKey_jiemi(data);

   QString ret=QString::fromStdString(rcvstr);
  return ret;
}
std::string Rsa_CLC::sendToServer(QString data)
{
    std::string str=data.toStdString();
    std::string sendstr=Server_publicKey_jiami(str);

    return  sendstr;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值