c++ DES ECB加密算法pkcs5padding填充实现

1 篇文章 0 订阅

我主要的实现的pkcs5padding填充,其他填充方式自己实现就好了,都不难。

使用的是静态连接的方法,使用的是openssl的libcrypto库,网上一大堆,这里就不贴了。

windows库:https://download.csdn.net/download/suhiymof/11247287

头文件这样包含即可:

#ifdef WIN32
#include "des.h"
#pragma comment(lib, "libcrypt" )
#else
#include "openssl/des.h"
#endif //  WIN32

填充代码

//填充
char* PKCS5Padding(string strParams, uint32 unBlockSize)
{
	int nRaw_size = strParams.size();
	int i=0, j=nRaw_size/8+1, k=nRaw_size%8;
	int nPidding_size = 8 - k;
	char* szArray;
	szArray = (char *)malloc(nRaw_size + nPidding_size);
	memcpy(szArray, strParams.c_str(), nRaw_size);
	for (int i1=nRaw_size; i1<(nRaw_size+nPidding_size); i1++) 
	{
		// PKCS5Padding 算法:
		szArray[i1] = nPidding_size;
	}
	return szArray;
}

windows加密:

//strParams:加密字符串
//szKey:加密的密码,我用的是八字节的密码
string Des_Encrypt(string strParams, char* szKey)
{
	using namespace CryptoPP;
	char szCommand[1024];
	memset(szCommand, 0, 1024);
	int nRaw_size = strParams.size();
	char* szArray = PKCS5Padding(strParams, DES::BLOCKSIZE);
	int j=nRaw_size/DES::BLOCKSIZE + 1;
	unsigned char key[DES::DEFAULT_KEYLENGTH];
	memcpy(key, szKey, DES::BLOCKSIZE);
	unsigned char szInput[ DES::BLOCKSIZE];
	unsigned char szOutput[ DES::BLOCKSIZE];
	for (int i = 0; i < j; ++i)
	{
		memset(szInput, 0, 8);
		memset(szOutput, 0, 8);
		memcpy(szInput, szArray+(i*8), 8);
		DESEncryption encryption_DES;
		//因此,设置密匙。
		encryption_DES.SetKey(key, DES::KEYLENGTH );
		//进行加密
		encryption_DES.ProcessBlock( szInput, szOutput);
		memcpy(szCommand+(i*8), szOutput, 8);
	}
	int nLen = j * 8;
    //base64编码
	std::string strTmp = base64_encode(reinterpret_cast<const unsigned char*>(szCommand), nLen);
	return strTmp;
}

linux加密:

string Des_Encrypt(string strParams, char* szKey)
{
	char szCommand[1024];
	memset(szCommand, 0, 1024);
	int nRaw_size = strParams.size();
	char* szArray = PKCS5Padding(strParams, sizeof(DES_cblock));
	int j=nRaw_size/8 + 1;
	DES_cblock sKey;// = "12341234";
	memcpy(sKey, szKey, 8);
	const_DES_cblock sInput;
	DES_cblock sOutput;
	DES_key_schedule sSchedule;
	//转换成schedule
	DES_set_key_unchecked(&sKey, &sSchedule); 
	for (int i = 0; i < j; ++i)
	{
		memset(sInput, 0, 8);
		memset(sOutput, 0, 8);
		memcpy(sInput, szArray+(i*8), 8);
		DES_ecb_encrypt(&sInput, &sOutput, &sSchedule, DES_ENCRYPT);
		memcpy(szCommand+(i*8), sOutput, 8);
	}
	int nLen = j * 8;
    //base64编码
	std::string strTmp = base64_encode(reinterpret_cast<const unsigned char*>(szCommand), nLen);
	return strTmp;
}

这里包含了base64位编码,这里贴一下源码

static const std::string base64_chars = 
             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
             "abcdefghijklmnopqrstuvwxyz"
             "0123456789+/";


static inline bool is_base64(unsigned char c) {
  return (isalnum(c) || (c == '+') || (c == '/'));
}

std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
	printf("---%d\n", in_len);
  std::string ret;
  int i = 0;
  int j = 0;
  unsigned char char_array_3[3];
  unsigned char char_array_4[4];

  while (in_len--) {
    char_array_3[i++] = *(bytes_to_encode++);
    if (i == 3) {
      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
      char_array_4[3] = char_array_3[2] & 0x3f;

      for(i = 0; (i <4) ; i++)
        ret += base64_chars[char_array_4[i]];
      i = 0;
    }
  }

  if (i)
  {
    for(j = i; j < 3; j++)
      char_array_3[j] = '\0';

    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
    char_array_4[3] = char_array_3[2] & 0x3f;

    for (j = 0; (j < i + 1); j++)
      ret += base64_chars[char_array_4[j]];

    while((i++ < 3))
      ret += '=';

  }

  //printf("---111%d, %s\n", ret.size(), ret.c_str());
  return ret;

}

std::string base64_decode(std::string const& encoded_string) {
  size_t in_len = encoded_string.size();
  int i = 0;
  int j = 0;
  int in_ = 0;
  unsigned char char_array_4[4], char_array_3[3];
  std::string ret;

  while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
    char_array_4[i++] = encoded_string[in_]; in_++;
    if (i ==4) {
      for (i = 0; i <4; i++)
        char_array_4[i] = base64_chars.find(char_array_4[i]);

      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

      for (i = 0; (i < 3); i++)
        ret += char_array_3[i];
      i = 0;
    }
  }

  if (i) {
    for (j = i; j <4; j++)
      char_array_4[j] = 0;

    for (j = 0; j <4; j++)
      char_array_4[j] = base64_chars.find(char_array_4[j]);

    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

    for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
  }

  return ret;
}

解密:

windows

string Des_Decrypt(std::string strEncryptData, char* szKey)
{
	using namespace CryptoPP;
	//base64解码
	strEncryptData = base64_decode(strEncryptData);
	string strRet;
	std::vector<unsigned char> vecCleartext;
	int nRaw_size = strEncryptData.length();
	int j=nRaw_size/DES::BLOCKSIZE;
	unsigned char key[DES::DEFAULT_KEYLENGTH];
	memcpy(key, szKey, DES::BLOCKSIZE);
	unsigned char szInput[ DES::BLOCKSIZE];
	unsigned char szOutput[ DES::BLOCKSIZE];
	const char* szData = strEncryptData.c_str();
	//解密
	for (int i = 0; i < j; ++i)
	{
		memset(szInput, 0, DES::BLOCKSIZE);
		memset(szOutput, 0, DES::BLOCKSIZE);
		memcpy(szInput, szData+(i*DES::BLOCKSIZE), DES::BLOCKSIZE);
		DESDecryption decryption_DES;
		//回忆一下之前的背景,对称加密算法需要一个密匙。加密和解密都会用到。
		//因此,设置密匙。
		decryption_DES.SetKey(key, DES::KEYLENGTH );
		//进行加密
		decryption_DES.ProcessBlock(szInput, szOutput);
		for (int k = 0; k < DES::BLOCKSIZE; k++)
			vecCleartext.push_back(szOutput[k]);
	}
	//填充数量
	int nPadNum = vecCleartext[nRaw_size-1];
	strRet.clear();
	strRet.assign(vecCleartext.begin(), vecCleartext.end()-nPadNum);
	return strRet;
}

linux:

string Des_Decrypt(std::string strEncryptData, char* szKey)
{
	//base64解码
	strEncryptData = base64_decode(strEncryptData);
	string strRet;
	std::vector<unsigned char> vecCleartext;
	DES_cblock sKey;
	memcpy(sKey, szKey, 8);
	DES_key_schedule sSchedule;
	//转换成schedule
	DES_set_key_unchecked(&sKey, &sSchedule); 
	const_DES_cblock sInput;
	DES_cblock sOutput;
	int nRaw_size = strEncryptData.length();
	int j=nRaw_size/8;
	const char* szData = strEncryptData.c_str();
	//解密
	unsigned char szTmp[8];
	for (int i = 0; i < j; ++i)
	{
		memset(sInput, 0, 8);
		memset(sOutput, 0, 8);
		memcpy(sInput, szData+(i*8), 8);
		DES_ecb_encrypt(&sInput, &sOutput, &sSchedule, DES_DECRYPT);
		for (int k = 0; k < 8; k++)
			vecCleartext.push_back(sOutput[k]);
	}
	//填充数量
	int nPadNum = vecCleartext[nRaw_size-1];
	strRet.clear();
	strRet.assign(vecCleartext.begin(), vecCleartext.end()-nPadNum);
	return strRet;
}

 

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值