基於OPEN SSL的幾種加密過程-DES,3DES,SHA256的實例

最近在做一個基於https的項目,因爲業務數據需要安全保障,於是需要一定的加解密工作,數據的安全也是現代互聯網發展的保障。
下面幾種加解密機制:

  1. DES、3DES加密

DES全稱爲Data Encryption Standard,即數據加密標準,是一種使用密鑰加密的塊算法,1977年被美國聯邦政府的國家標準局確定爲聯邦資料處理標準(FIPS),並授權在非密級政府通信中使用,隨後該算法在國際上廣泛流傳開來。需要注意的是,在某些文獻中,作爲算法的DES稱爲數據加密算法(Data Encryption Algorithm,DEA),已與作爲標準的DES區分開來。
DES對稱加密,是一種比較傳統的加密方式,其加密運算、解密運算使用的是同樣的密鑰,信息的發送者和信息的接收者在進行信息的傳輸與處理時,必須共同持有該密碼(稱爲對稱密碼),是一種對稱加密算法。
DES 的常見變體是三重 DES,使用 168 位的密鑰對資料進行三次加密的一種機制;它通常(但非始終)提供極其強大的安全性。如果三個 56 位的子元素都相同,則三重 DES 向後兼容 DES。

DES加密過程:

#include <openssl/des.h>
#include <openssl/rand.h>
/*
注意:傳進傳出的參數皆爲16進制字符數據

使用DES算法對數據加密
desKey	密鑰,支持單倍、雙倍、三倍
data	源數據 長度必須爲8的倍數
mode 	加密模式 ECB CBC CFB
iv	僅 CBC CFB兩種模式纔有此值,長度爲8字節
返回值:
>=0 加密數據的長度
<0 錯誤碼
*/
int DesEncryptData(const std::string &desKeyHexStr, const std::string &dataHexStr, int mode, const std::string &iv, std::string &encDataHexStr)
{
	
	BYTE desKey[MAX_SIZE_L] = {0};
	std::string data ;
	std::string encData;
	int keyLen = 0, x = 0;
	long dataLen = 0;
	DES_key_schedule ks1, ks2, ks3;
	unsigned char tmpData[8], ke1[8], ke2[8], ke3[8], ivec[8];
	unsigned char input[MAX_SIZE_L], output[MAX_SIZE_L];

	keyLen = desKeyHexStr.length()/2;
	dataLen = dataHexStr.length()/2;

	if (keyLen == 0 || dataLen == 0)
		return -1;//errCodeOffsetOfCommon_CodeParameter;

	memset(input, 0, MAX_SIZE_L);
	memset(output, 0, MAX_SIZE_L);
	memset(desKey, 0, MAX_SIZE_L);
	
	hexToBytes(dataHexStr,input);
	hexToBytes(desKeyHexStr,desKey);

	switch (keyLen)
	{
	case 8:
		memset(ke1, 0, 8);  
		memcpy(ke1, desKey, 8);
		DES_set_key_unchecked((const_DES_cblock*)ke1, &ks1);  

		switch (mode)
		{
		case CBC:
			memcpy(ivec, iv.c_str(), 8);
			DES_cbc_encrypt(input, output, dataLen, &ks1, (DES_cblock *)ivec, DES_ENCRYPT);
			break;
		case CFB:
			memcpy(ivec, iv.c_str(), 8);
			DES_cfb_encrypt(input, output, 8, dataLen, &ks1, (DES_cblock *)ivec, DES_ENCRYPT);
			break;
		case ECB:
		default:
			for (x=0;x<dataLen;x+=8)
			{
				memcpy(tmpData, input+x, 8); 
				DES_ecb_encrypt((const_DES_cblock*)tmpData, (DES_cblock *)(output+x), &ks1, DES_ENCRYPT);
			}
			break;
		}
		break;

	case 16:
	case 24:
		memset(ke1, 0, 8);  
		memset(ke2, 0, 8);  
		memset(ke3, 0, 8); 

		if (keyLen == 16)
		{
			memcpy(ke1, desKey, 8);
			memcpy(ke2, desKey+8, 8);
			memcpy(ke3, desKey, 8);
		}else
		{
			memcpy(ke1, desKey, 8);
			memcpy(ke2, desKey+8, 8);
			memcpy(ke3, desKey+16, 8);
		}

		DES_set_key_unchecked((const_DES_cblock*)ke1, &ks1);  
		DES_set_key_unchecked((const_DES_cblock*)ke2, &ks2);  
		DES_set_key_unchecked((const_DES_cblock*)ke3, &ks3);  

		switch (mode)
		{
		case CBC:
			memcpy(ivec, iv.c_str(), 8);
			DES_ede3_cbc_encrypt(input, output, dataLen, &ks1, &ks2, &ks3, (DES_cblock *)ivec, DES_ENCRYPT);
			break;
		case CFB:
			memcpy(ivec, iv.c_str(), 8);
			DES_ede3_cfb_encrypt(input, output, 8, dataLen, &ks1, &ks2, &ks3, (DES_cblock *)ivec, DES_ENCRYPT);
		case ECB:
		default:
			for (x=0;x<dataLen;x+=8)
			{
				memcpy(tmpData, input+x, 8); 
				DES_ecb3_encrypt((const_DES_cblock*)tmpData, (DES_cblock *)(output+x), &ks1, &ks2, &ks3, DES_ENCRYPT);
			}
			break;
		}
		break;

	default:
		dataLen = -1;//errCodeOffsetOfCommon_CodeParameter;
		break;
	}

	if (dataLen > 0)
	{
		encDataHexStr = bytesToHexString(output,dataLen);
	}

	return encDataHexStr.length();
}

//密鑰key:4a776d4e5ba6a68aec14abc9d7df9714
//加密原數據:hello,world!
//轉換成16進制字符的80pad:68656c6c6f2c776f726c642180000000
//80pad轉換成16進制字符串data:3638363536633663366632633737366637323663363432313830303030303030
//將data和key傳參進去,
std::string enData;
int len = DesEncryptData(key,data,ECB,"",enData);
//得到3Des加密後的結果是enData:547f98962becbd93897b96aa44971c384853b21511529e2dceb58a11940ca037

解密過程:

/*
使用DES算法對數據解密
desKey	密鑰,支持單倍、雙倍、三倍
data	源數據 長度必須爲8的倍數
mode 	加密模式 ECB CBC CFB
iv	僅CBC CFB兩種模式纔有此值
*/
int DesDecryptData(const std::string &desKeyHexStr, const std::string &dataHexStr, int mode, const std::string &iv, std::string &plainDataHexStr)
{
	BYTE desKey[MAX_SIZE_L];
	//std::string desKey;// = hexStringToString(desKeyHexStr);
	std::string data;// = hexStringToString(dataHexStr);
	int keyLen = 0, x = 0;
	long dataLen = 0;
	DES_key_schedule ks1, ks2, ks3;
	unsigned char tmpData[8], ke1[8], ke2[8], ke3[8], ivec[8];  
	unsigned char input[MAX_SIZE_L], output[MAX_SIZE_L];

	keyLen = desKeyHexStr.length()/2;
	dataLen = dataHexStr.length()/2;

	if (keyLen == 0 || dataLen == 0)
		return -1;//errCodeOffsetOfCommon_CodeParameter;

	memset(desKey,0,MAX_SIZE_L);
	memset(input, 0, MAX_SIZE_L);
	memset(output, 0, MAX_SIZE_L);
	//memcpy(input, data.c_str(), dataLen);
	hexToBytes(dataHexStr,input);
	hexToBytes(desKeyHexStr,desKey);

	switch (keyLen)
	{
	case 8:
		memset(ke1, 0, 8);  
		memcpy(ke1, desKey, 8);
		DES_set_key_unchecked((const_DES_cblock*)ke1, &ks1);  

		switch (mode)
		{
		case CBC:
			memcpy(ivec, iv.c_str(), 8);
			DES_cbc_encrypt(input, output, dataLen, &ks1, (DES_cblock *)ivec, DES_DECRYPT);
			break;
		case CFB:
			memcpy(ivec, iv.c_str(), 8);
			DES_cfb_encrypt(input, output, 8, dataLen, &ks1, (DES_cblock *)ivec, DES_DECRYPT);
			break;
		case ECB:
		default:
			for (x=0;x<dataLen;x+=8)
			{
				memcpy(tmpData, input+x, 8); 
				DES_ecb_encrypt((const_DES_cblock*)tmpData, (DES_cblock *)(output+x), &ks1, DES_DECRYPT);
			}
			break;
		}
		break;

	case 16:
	case 24:
		memset(ke1, 0, 8);  
		memset(ke2, 0, 8);  
		memset(ke3, 0, 8); 

		if (keyLen == 16)
		{
			memcpy(ke1, desKey, 8);
			memcpy(ke2, desKey+8, 8);
			memcpy(ke3, desKey, 8);
		}else
		{
			memcpy(ke1, desKey, 8);
			memcpy(ke2, desKey+8, 8);
			memcpy(ke3, desKey+16, 8);
		}

		DES_set_key_unchecked((const_DES_cblock*)ke1, &ks1);  
		DES_set_key_unchecked((const_DES_cblock*)ke2, &ks2);  
		DES_set_key_unchecked((const_DES_cblock*)ke3, &ks3);  

		switch (mode)
		{
		case CBC:
			memcpy(ivec, iv.c_str(), 8);
			DES_ede3_cbc_encrypt(input, output, dataLen, &ks1, &ks2, &ks3, (DES_cblock *)ivec, DES_DECRYPT);
			break;
		case CFB:
			memcpy(ivec, iv.c_str(), 8);
			DES_ede3_cfb_encrypt(input, output, 8, dataLen, &ks1, &ks2, &ks3, (DES_cblock *)ivec, DES_DECRYPT);
		case ECB:
		default:
			for (x=0;x<dataLen;x+=8)
			{
				memcpy(tmpData, input+x, 8); 
				DES_ecb3_encrypt((const_DES_cblock*)tmpData, (DES_cblock *)(output+x), &ks1, &ks2, &ks3, DES_DECRYPT);
			}
			break;
		}
		break;

	default:
		dataLen = -1;//errCodeOffsetOfCommon_CodeParameter;
		break;
	}

	if (dataLen > 0)
	{
		/*std::string result((char *)output, dataLen);
		plainDataHexStr = encodeHexString(result);*/
		plainDataHexStr = bytesToHexString(output,dataLen);
	}
	return plainDataHexStr.length();
}

//解密傳參data:547f98962becbd93897b96aa44971c384853b21511529e2dceb58a11940ca037
//key:4a776d4e5ba6a68aec14abc9d7df9714
std::string decData;
int len = DesDecryptData(key,data,ECB,"",decData);
//decData:3638363536633663366632633737366637323663363432313830303030303030
//得到80pad:68656c6c6f2c776f726c642180000000
//轉換得到16進制字符串:68656c6c6f2c776f726c6421
//16進制轉bytes:hello,world! 
  1. SHA256 (salt)

SHA代表安全哈希算法。SHA-1和SHA-2是該算法不同的兩個版本,它們的構造和簽名的長度都有所不一樣,但可以把SHA-2理解爲SHA-1的繼承者。

首先,人們一般把哈希值位數長度作爲重要的區別,SHA-1是160位的哈希值,而SHA-2是組合值,有不同的位數,其中最受歡迎的是256位。

因爲SHA-2有多種不同的位數,導致這個名詞有一些混亂。但是無論是“SHA-2”,“SHA-256”或“SHA-256位”,其實都是指同一種加密算法。但是SHA-224”,“SHA-384”或“SHA-512”,表示SHA-2的二進制長度。還要另一種就是會把算法和二進制長度都寫上,如“SHA-2
384”。

SSL行業選擇SHA作爲數字簽名的散列算法,從2011到2015,一直以SHA-1位主導算法。但隨着互聯網技術的提升,SHA-1的缺點越來越突顯。從去年起,SHA-2成爲了新的標準,所以現在簽發的SSL證書,必須使用該算法簽名。
作者:ROW供享社
鏈接:https://www.jianshu.com/p/68c664b663f4
來源:簡書

加鹽算法:其實就是在需要加密的數據後面增加一串隨機數進行加密即可。爲什麼要加鹽呢,其實就是爲了高安全性。加鹽必須隨機纔有用。https://blog.csdn.net/M_Kerry/article/details/82725622#3salt_30

#include "openssl/sha.h"  

std::string mingwen = "123456";
unsigned char mdStr[33] = {0};//hash後的值長度爲32個字節,也就是256個bit
SHA256((const unsigned char *)mingwen.c_str(),mingwen.length(),mdStr);
std::string res = bytesToHexString(mdStr,32);//字節數組轉16進制字符串
//長度64位的16進制字符串res:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章