我主要的实现的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;
}