Windows自带的加密算法Crypto实现MD5, AES256以及RSA算法

密码学我了解的很少,但是在逆向中这却是非常重要的基础。这个Crypto函数库是windows自带的,我实现了散列算法MD5[128位], 对称加密算法AES[256位]以及RSA算法。散列函数实现改几个参数就能成SHA算法了。

1. MD5

// 单向散列函数
BOOL OneWayHash(PBYTE pData, DWORD dwSize, ALG_ID cType)
{
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTHASH hCryptHash = NULL;
	PBYTE pHashData = NULL;
	BOOL fOk = FALSE;
	DWORD dwHashLen = 0, dwDataLen = sizeof(dwHashLen);

	do
	{
		fOk = CryptAcquireContextA(&hCryptProv,
			NULL,
			NULL,
			PROV_RSA_AES,
			CRYPT_VERIFYCONTEXT
		);
		if (!fOk)
		{
			break;
		}
		// 创建一个空的HASH对象
		fOk = CryptCreateHash(hCryptProv, cType, NULL, 0, &hCryptHash);
		if (!fOk)
		{
			break;
		}
		// 生成对应的哈希值
		if (!CryptHashData(hCryptHash, pData, dwSize, 0))
		{
			break;
		}
		if (!CryptGetHashParam(hCryptHash, HP_HASHSIZE, (PBYTE)&dwHashLen, &dwDataLen, 0))
		{
			break;
		}
		pHashData = new BYTE[dwHashLen];
		if (NULL == pHashData)
		{
			break;
		}
		if (!CryptGetHashParam(hCryptHash, HP_HASHVAL, pHashData, &dwHashLen, 0))
		{
			break;
		}
		fOk = TRUE;
	} while (FALSE);

	if (fOk)
	{
		for (size_t nIdx = 0; nIdx < dwHashLen; ++nIdx)
		{
			printf("%02X", pHashData[nIdx]);
		}
		putchar('\n');
	}
	if (NULL != pHashData)
	{
		delete[] pHashData;
		pHashData = NULL;
	}
	if (NULL != hCryptProv)
	{
		CryptReleaseContext(hCryptProv, 0);
		hCryptProv = NULL;
	}
	if (NULL != hCryptHash)
	{
		CryptDestroyHash(hCryptHash);
		hCryptHash = NULL;
	}
	
	return(fOk);
}

2. AES

BOOL FileWriteBack(const char *pcszFilePathName, PBYTE pbData, size_t nBufSize)
{
	BOOL fOk = FALSE;
	FILE *fp = NULL;

	fp = fopen(pcszFilePathName, "wb");
	if (NULL == fp)
	{
		return(fOk);
	}
	fwrite(pbData, nBufSize, 1, fp);
	if (NULL != fp)
	{
		fclose(fp);
		fp = NULL;
	}
	fOk = TRUE;

	return(fOk);
}


BOOL ReadFromFile(LPCSTR lpcszFilePathName, PBYTE *ppData, DWORD &dwFileSize, size_t &nFileBufLen)
{
	BOOL fOk = FALSE;
	FILE *fp = NULL;
	LONG lSize = 0;
	PBYTE pbData = NULL;

	fp = fopen(lpcszFilePathName, "rb");
	if (NULL == fp)
	{
		return(FALSE);
	}
	fseek(fp, 0, SEEK_END);
	lSize = ftell(fp);
	pbData = new BYTE[lSize * 16];
	RtlZeroMemory(pbData, lSize * 16);
	dwFileSize = lSize;
	nFileBufLen = lSize * 16;
	fseek(fp, 0, SEEK_SET);
	fread(pbData, lSize, 1, fp);
	if (NULL != fp)
	{
		fclose(fp);
		fp = NULL;
	}
	*ppData = pbData;

	return(TRUE);
}


// 256位AES算法加密与解密
BOOL AESEncrypt(const PBYTE pcszPassword, size_t nPassSize, LPCSTR lpcszOrigFilePathName, LPCSTR lpcszEncFilePathName)
{
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTHASH hCryptHash = NULL;
	HCRYPTKEY hCryptKey = NULL;
	BOOL fOk = FALSE;
	PBYTE pbData = NULL;
	DWORD dwSize = 0;
	size_t nBufLen = 0;

	do
	{
		if (!ReadFromFile(lpcszOrigFilePathName, &pbData, dwSize, nBufLen))
		{
			break;
		}
		if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
		{
			break;
		}
		if (!CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash))
		{
			break;
		}
		if (!CryptHashData(hCryptHash, pcszPassword, nPassSize, 0))
		{
			break;
		}
		if (!CryptDeriveKey(hCryptProv, CALG_AES_256, hCryptHash, CRYPT_EXPORTABLE, &hCryptKey))
		{
			break;
		}
		if (!CryptEncrypt(hCryptKey, NULL, TRUE, 0, pbData, &dwSize, nBufLen))
		{
			break;
		}
		fOk = FileWriteBack(lpcszEncFilePathName, pbData, dwSize);
	} while (FALSE);
	if (NULL != hCryptProv)
	{
		CryptReleaseContext(hCryptProv, 0);
		hCryptProv = NULL;
	}
	if (NULL != hCryptHash)
	{
		CryptDestroyHash(hCryptHash);
		hCryptHash = NULL;
	}
	if (NULL != hCryptKey)
	{
		CryptDestroyKey(hCryptKey);
		hCryptKey = NULL;
	}
	if (NULL != pbData)
	{
		delete[] pbData;
		pbData = NULL;
	}
	
	return(fOk);
}

BOOL AESDecrypt(const PBYTE pcszPassword, 
	size_t nPassSize,
	LPCSTR lpcszOrigFilePathName, 
	LPCSTR lpcszEncFilePathName
	)
{
	BOOL fOk = FALSE;
	PBYTE pbData = NULL;
	DWORD dwFileLen = 0;
	size_t nBufSize = 0;
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTHASH hCryptHash = NULL;
	HCRYPTKEY hCryptKey = NULL;

	do
	{
		if (!ReadFromFile(lpcszOrigFilePathName, &pbData, dwFileLen, nBufSize))
		{
			break;
		}
		if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
		{
			break;
		}
		if (!CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash))
		{
			break;
		}
		if (!CryptHashData(hCryptHash, pcszPassword, nPassSize, 0))
		{
			break;
		}
		if (!CryptDeriveKey(hCryptProv, CALG_AES_256, hCryptHash, 0, &hCryptKey))
		{
			break;
		}
		if (!CryptDecrypt(hCryptKey, NULL, TRUE, 0, pbData, &dwFileLen))
		{
			break;
		}
		if (!FileWriteBack(lpcszEncFilePathName, pbData, dwFileLen))
		{
			break;
		}
		fOk = TRUE;
	} while (FALSE);
	if (NULL != pbData)
	{
		delete[] pbData;
		pbData = NULL;
	}
	if (NULL != hCryptProv)
	{
		CryptReleaseContext(hCryptProv, 0);
		hCryptProv = NULL;
	}
	if (NULL != hCryptHash)
	{
		CryptDestroyHash(hCryptHash);
		hCryptHash = NULL;
	}
	if (NULL != hCryptKey)
	{
		CryptDestroyKey(hCryptKey);
		hCryptKey = NULL;
	}

	return(fOk);
}

3. RSA

BOOL FileWriteBack(const char *pcszFilePathName, PBYTE pbData, size_t nBufSize)
{
	BOOL fOk = FALSE;
	FILE *fp = NULL;

	fp = fopen(pcszFilePathName, "wb");
	if (NULL == fp)
	{
		return(fOk);
	}
	fwrite(pbData, nBufSize, 1, fp);
	if (NULL != fp)
	{
		fclose(fp);
		fp = NULL;
	}
	fOk = TRUE;

	return(fOk);
}


BOOL ReadFromFile(LPCSTR lpcszFilePathName, PBYTE *ppData, DWORD &dwFileSize, size_t &nFileBufLen)
{
	BOOL fOk = FALSE;
	FILE *fp = NULL;
	LONG lSize = 0;
	PBYTE pbData = NULL;

	fp = fopen(lpcszFilePathName, "rb");
	if (NULL == fp)
	{
		return(FALSE);
	}
	fseek(fp, 0, SEEK_END);
	lSize = ftell(fp);
	pbData = new BYTE[lSize * 16];
	RtlZeroMemory(pbData, lSize * 16);
	dwFileSize = lSize;
	nFileBufLen = lSize * 16;
	fseek(fp, 0, SEEK_SET);
	fread(pbData, lSize, 1, fp);
	if (NULL != fp)
	{
		fclose(fp);
		fp = NULL;
	}
	*ppData = pbData;

	return(TRUE);
}

BOOL GenericKey(PBYTE *ppPublicKey, DWORD *pdwPublicKeyLength, PBYTE *ppPrivateKey, PDWORD pdwPrivateKeyLength)
{
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTKEY hCryptKey = NULL;
	DWORD dwPrivateKeyLength = 0;
	DWORD dwPublicKeyLength = 0;
	PBYTE pPublicKey = NULL;
	PBYTE pPrivateKey = NULL;
	BOOL fOk = FALSE;

	do
	{
		if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
		{
			break;
		}
		// 生成公私钥对
		if (!CryptGenKey(hCryptProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hCryptKey))
		{
			break;
		}
		// 获取公钥的长度
		if (!CryptExportKey(hCryptKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyLength))
		{
			break;
		}
		pPublicKey = new BYTE[dwPublicKeyLength];
		RtlZeroMemory(pPublicKey, dwPublicKeyLength);
		// 获取公钥
		if (!CryptExportKey(hCryptKey, NULL, PUBLICKEYBLOB, 0, pPublicKey, &dwPublicKeyLength))
		{
			break;
		}
		
		// 获取私钥长度
		if (!CryptExportKey(hCryptKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyLength))
		{
			break;
		}
		pPrivateKey = new BYTE[dwPrivateKeyLength];
		RtlZeroMemory(pPrivateKey, dwPrivateKeyLength);
		// 生成私钥
		if (!CryptExportKey(hCryptKey, NULL, PRIVATEKEYBLOB, 0, pPrivateKey, &dwPrivateKeyLength))
		{
			break;
		}
		fOk = TRUE;
		*ppPublicKey = pPublicKey;
		*pdwPublicKeyLength = dwPublicKeyLength;
		*ppPrivateKey = pPrivateKey;
		*pdwPrivateKeyLength = dwPrivateKeyLength;
	} while (FALSE);

	if (hCryptKey)
	{
		CryptDestroyKey(hCryptKey);
	}
	if (hCryptProv)
	{
		CryptReleaseContext(hCryptProv, 0);
	}

	return(fOk);
}

BOOL RSAEncrypt(PBYTE pPublicKey, DWORD dwPublicKeyLength, PBYTE pData, DWORD &dwDataLength, DWORD dwBufferLength)
{
	BOOL fOk = FALSE;
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTKEY hCryptKey = NULL;

	do
	{
		fOk = CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
		if (!fOk)
		{
			break;
		}
		fOk = CryptImportKey(hCryptProv, pPublicKey, dwPublicKeyLength, NULL, 0, &hCryptKey);
		if (!fOk)
		{
			break;
		}
		fOk = CryptEncrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength, dwBufferLength);
	} while (FALSE);

	return(fOk);
}

BOOL RSADecrypt(PBYTE pPrivateKey, DWORD dwPrivateLength, PBYTE pData, DWORD &dwDataLength)
{
	BOOL fOk = FALSE;
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTKEY hCryptKey = NULL;

	do
	{
		if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
		{
			break;
		}
		if (!CryptImportKey(hCryptProv, pPrivateKey, dwPrivateLength, NULL, 0, &hCryptKey))
		{
			break;
		}
		if (!CryptDecrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength))
		{
			break;
		}
		fOk = TRUE;
	} while (FALSE);
	if (hCryptKey)
	{
		CryptDestroyKey(hCryptKey);
	}
	if (hCryptProv)
	{
		CryptReleaseContext(hCryptProv, 0);
	}

	return(fOk);
}

(完)

CAN长字节DM1报文是指在CAN总线上传输的长度超过8个字节的DM1报文。根据引用\[1\],当要传输的数据长度超过8个字节时,首先使用TPCM进行广播,广播内容包含即将传输报文的PGN、总的数据包长度等信息,然后使用TP.DT进行数据传输。相邻两个TP.DT之间的时间间隔是50ms到200ms。根据引用\[2\],当字节数大于8时,将会使用多帧传输参数组。根据引用\[3\],DM1报文是Diagnostic Message 1, Active Diagnostic Trouble Codes的缩写,用于点亮故障指示灯、红色停机灯等,并周期性播报控制器中处于激活状态的故障码。DM1报文的格式包括各个字节的定义,如故障指示灯、红色停机灯、琥珀色警告指示灯等。因此,CAN长字节DM1报文是指在CAN总线上传输的长度超过8个字节的DM1报文,用于传输更多的故障码信息。 #### 引用[.reference_title] - *1* [车载通信——J1939 DM1](https://blog.csdn.net/weixin_64064747/article/details/130193432)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [J1939广播DM1报文](https://blog.csdn.net/mengdeguodu_/article/details/108173263)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [J1939商用车在线诊断DM1报文](https://blog.csdn.net/traveller93/article/details/120735912)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值