VC++使用OpenSSL的DES加密


引用: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 ;  
}

我是根據自己的情況封裝。
發佈了44 篇原創文章 · 獲贊 27 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章