引用:http://www.cnblogs.com/findumars/p/7252839.html
使用OpenSSL的库,需要先安装或编译OpenSSL。
我是在这里使用别人编译的开发版:http://slproweb.com/products/Win32OpenSSL.html。安装后把安装目录中的include,bin,lib目录中的文件放到自己的工程目录中。
我这里直接略过了。
DES_Openssl.h
#pragma once
#include <string>
using namespace std;
const string m_desKey = "20171010";
class CDes_Openssl
{
public:
CDes_Openssl(void);
~CDes_Openssl(void);
public:
CString MyDesDecrypt(CString strCipher);//解密
CString MyDesEncrypt(CString strClear);//加密
private:
std::string des_encrypt(const std::string &clearText, const std::string &key);
std::string des_decrypt(const std::string &cipherText, const std::string &key);
private:
//下面加的是转换函数,如果不是mfc程序,可以忽略,直接用des_encrypt,des_decrypt加解密
void Multi2Wide(const char* pSource, CString& strGet);
void Wide2MultiChar(CString& strSource, char* pResult);
//字节流转换为十六进制字符串
void Hex2Str( const char *sSrc, char *sDest, int nSrcLen );
//字节流转换为十六进制字符串
void ByteToHexStr(const unsigned char* source, char* dest, int sourceLen);
//十六进制字符串转换为字节流
void HexStrToByte(const char* source, unsigned char* dest, int sourceLen);
};
DES_Openssl.cpp
#include "StdAfx.h"
#include "Des_Openssl.h"
#include "openssl/des.h"
#include <vector>
CDes_Openssl::CDes_Openssl(void)
{
}
CDes_Openssl::~CDes_Openssl(void)
{
}
// ---- des对称加解密 ---- //
// 加密 ecb模式
std::string CDes_Openssl::des_encrypt(const std::string &clearText, const std::string &key)
{
std::string cipherText; // 密文
DES_cblock keyEncrypt;
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);
// 循环加密,每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_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);
memcpy(tmp, outputText, 8);
for (int j = 0; j < 8; j++)
vecCiphertext.push_back(tmp[j]);
}
if (clearText.length() % 8 != 0)
{
int tmp1 = clearText.length() / 8 * 8;
int tmp2 = clearText.length() - tmp1;
memset(inputText, 0, 8);
memcpy(inputText, clearText.c_str() + tmp1, tmp2);
// 加密函数
DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);
memcpy(tmp, outputText, 8);
for (int j = 0; j < 8; j++)
vecCiphertext.push_back(tmp[j]);
}
cipherText.clear();
cipherText.assign(vecCiphertext.begin(), vecCiphertext.end());
return cipherText;
}
// 解密 ecb模式
std::string CDes_Openssl::des_decrypt(const std::string &cipherText, const std::string &key)
{
std::string clearText; // 明文
DES_cblock keyEncrypt;
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);
const_DES_cblock inputText;
DES_cblock outputText;
std::vector<unsigned char> vecCleartext;
unsigned char tmp[8];
for (int i = 0; i < cipherText.length() / 8; i++)
{
memcpy(inputText, cipherText.c_str() + i * 8, 8);
DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);
memcpy(tmp, outputText, 8);
for (int j = 0; j < 8; j++)
vecCleartext.push_back(tmp[j]);
}
if (cipherText.length() % 8 != 0)
{
int tmp1 = cipherText.length() / 8 * 8;
int tmp2 = cipherText.length() - tmp1;
memset(inputText, 0, 8);
memcpy(inputText, cipherText.c_str() + tmp1, tmp2);
// 解密函数
DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);
memcpy(tmp, outputText, 8);
for (int j = 0; j < 8; j++)
vecCleartext.push_back(tmp[j]);
}
clearText.clear();
clearText.assign(vecCleartext.begin(), vecCleartext.end());
return clearText;
}
CString CDes_Openssl::MyDesDecrypt(CString strIn)
{
CString strRet = 0;
char szCipher[1024];
Wide2MultiChar(strIn, szCipher);
char szDest[1024] = {0};
HexStrToByte(szCipher, (unsigned char*)szDest, strlen(szCipher));
string strR = szDest;
string strClear = des_decrypt(strR, m_desKey);
Multi2Wide(strClear.c_str(), strRet);
return strRet;
}
CString CDes_Openssl::MyDesEncrypt(CString strIn)//加密
{
char szClear[50] = {0};
Wide2MultiChar(strIn, szClear);
string strClear = szClear;
string strCipher = des_encrypt(strClear, m_desKey);
char szEncryptTxt[1024] = { 0 };
Hex2Str(strCipher.c_str(), szEncryptTxt, strCipher.length());
CString strRet1;
Multi2Wide(szEncryptTxt, strRet1);
return strRet1;
}
void CDes_Openssl::Multi2Wide(const char* pSource, CString& strGet)
{
DWORD dwNum = MultiByteToWideChar(CP_ACP, 0, pSource, -1, NULL, 0);
TCHAR* szIP = new TCHAR[dwNum];
//nRetLen = dwNum;
memset(szIP, 0, dwNum);
MultiByteToWideChar(CP_ACP, 0, pSource, -1, szIP, dwNum);
strGet = szIP;
delete[] szIP;
}
void CDes_Openssl::Wide2MultiChar(CString& strSource, char* pResult)
{
DWORD dwNum = WideCharToMultiByte(CP_ACP, 0, strSource, -1, NULL, 0, NULL, NULL);
//char* szRet = new char[dwNum + 1];
int nLen = dwNum;
//memset(szRet, 0, dwNum + 1);
WideCharToMultiByte(CP_ACP, 0, strSource, -1, pResult, dwNum, NULL, NULL);
}
void CDes_Openssl::Hex2Str(const char *sSrc, char *sDest, int nSrcLen)
{
int i;
char szTmp[3];
for( i = 0; i < nSrcLen; i++ )
{
sprintf( szTmp, "%02X", (unsigned char) sSrc[i] );
memcpy( &sDest[i * 2], szTmp, 2 );
}
return ;
}
void CDes_Openssl::ByteToHexStr(const unsigned char* source, char* dest, int sourceLen)
{
short i;
unsigned char highByte, lowByte;
for (i = 0; i < sourceLen; i++)
{
highByte = source[i] >> 4;
lowByte = source[i] & 0x0f ;
highByte += 0x30;
if (highByte > 0x39)
dest[i * 2] = highByte + 0x07;
else
dest[i * 2] = highByte;
lowByte += 0x30;
if (lowByte > 0x39)
dest[i * 2 + 1] = lowByte + 0x07;
else
dest[i * 2 + 1] = lowByte;
}
return ;
}
void CDes_Openssl::HexStrToByte(const char* source, unsigned char* dest, int sourceLen)
{
short i;
unsigned char highByte, lowByte;
for (i = 0; i < sourceLen; i += 2)
{
highByte = toupper(source[i]);
lowByte = toupper(source[i + 1]);
if (highByte > 0x39)
highByte -= 0x37;
else
highByte -= 0x30;
if (lowByte > 0x39)
lowByte -= 0x37;
else
lowByte -= 0x30;
dest[i / 2] = (highByte << 4) | lowByte;
}
return ;
}
我是根据自己的情况封装。