QT上位机开发(加密和解密)

发布时间:2024年01月13日

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

? ? ? ? 加密和解密是我们在软件开发中经常遇到的一种情形。最早的时候,加密是用在军事上面。现在由于各个行业、各个公司之间的竞争也非常激烈,因此有必要利用加密方法来保证自己软件的数据不被破解。此外,加解密还有一个重要的应用场合,那就是软件的有效期,这部分很多时候也是加密特定的文件,最后被软件加载和解密使用的。

? ? ? ? 不过可惜的是,目前为止在qt上面没有看到比较好的加解密库。还在window平台提供类类似的加解密api,也可以用来进行数据处理。

1、创建基本的qt widget环境

? ? ? ? 首先我们可以创建一个基本的widget环境,主要是用来生成编译环境比较方便。

2、代码说明

? ? ? ? 本次文中引用的代码主要来自这篇文章,大家可以参考一下原来作者的思路和想法。

https://blog.csdn.net/weixin_41077112/article/details/132753791

3、算法流程

? ? ? ? 如果用windows api进行数据数据的加解密,其实流程不算复杂。一般来说,先利用CryptAcquireContext创建一个HCRYPTPROV,再创建一个HCRYPTKEY。后期利用HCRYPTKEY进行数据的加密和解密动作。所有操作都做完,如果没有其他的工作,还需要把

前面资源释放一下。

int main()
{
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTKEY hKey = NULL;
	BYTE* pDataToEncrypt = (BYTE*)"Hello, World!";
	BYTE* pEncryptedData = NULL;
	DWORD encryptedDataLen = 0;
	BYTE* pDecryptedData = NULL;
	DWORD decryptedDataLen = 0;

	//Get the handler of Crypt Service Provider(CSP)
	if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, 0)) {
		printf("CryptAcquireContext failed: %d\n", GetLastError());
		return 1;
	}

	//Generate AES key
	if (!CryptGenKey(hCryptProv, CALG_AES_256, 0, &hKey)) {
		printf("CryptGenKey failed: %d\n", GetLastError());
		CryptReleaseContext(hCryptProv, 0);
		return 1;
	}

	//Encrypt data
	if (EncryptData(hKey, pDataToEncrypt, strlen((char*)pDataToEncrypt) + 1, &pEncryptedData, &encryptedDataLen)) {
		printf("Data encrypted successfully.\n");
		printf("Encrypted data: ");
		for (DWORD i = 0; i < encryptedDataLen; i++)
		{
			printf("%02X", pEncryptedData[i]);
		}
		printf("\n");

		//Decrypt data
		if (DecryptData(hKey, pEncryptedData, encryptedDataLen, &pDecryptedData, &decryptedDataLen)) {
			printf("Decrypted data: %s\n", pDecryptedData);
			free(pDecryptedData);
		}

		free(pEncryptedData);
	}

	//Clean resources
	CryptDestroyKey(hKey);
	CryptReleaseContext(hCryptProv, 0);

	return 0;
}

4、数据加密

? ? ? ? 数据加密的过程主要采用了CryptEncrypt函数,大家可以参考下,

#include <windows.h>
#include <wincrypt.h>
#include <iostream>

// encrypt data here
BOOL EncryptData(HCRYPTKEY hKey, BYTE* pData, DWORD dataLen, BYTE** ppEncryptedData, DWORD* pEncryptedDataLen)
{
	*pEncryptedDataLen = dataLen + 16;
	*ppEncryptedData = (BYTE*)malloc(*pEncryptedDataLen);
	ZeroMemory(*ppEncryptedData, *pEncryptedDataLen);
	if (*ppEncryptedData == NULL)
	{
		printf("Memory allocation failed.\n");
		return FALSE;
	}

	memcpy(*ppEncryptedData, pData, dataLen);
	if (!CryptEncrypt(hKey, NULL, TRUE, 0, *ppEncryptedData, &dataLen, *pEncryptedDataLen))
	{
		printf("CryptEncrypt failed: %d\n", GetLastError());
		free(*ppEncryptedData);

		if (GetLastError() == ERROR_MORE_DATA)
		{
			*pEncryptedDataLen = dataLen + 1;
			*ppEncryptedData = (BYTE*)malloc(*pEncryptedDataLen);
			ZeroMemory(*ppEncryptedData, *pEncryptedDataLen);
			if (*ppEncryptedData == NULL)
			{
				printf("Memory allocation failed again.\n");
				return FALSE;
			}
			memcpy(*ppEncryptedData, pData, dataLen);
			if (!CryptEncrypt(hKey, NULL, TRUE, 0, *ppEncryptedData, &dataLen, *pEncryptedDataLen))
			{
				printf("CryptEncrypt failed again: %d\n", GetLastError());
				free(*ppEncryptedData);
				return FALSE;
			}
		}
		else
		{
			return FALSE;
		}
	}

	*pEncryptedDataLen = dataLen;
	return TRUE;
}

5、数据解密

? ? ? ? 数据解密,则引用了另外一个api,即CryptDecrypt。

BOOL DecryptData(HCRYPTKEY hKey, BYTE* pEncryptedData, DWORD encryptedDataLen, BYTE** ppDecryptedData, DWORD* pDecryptedDataLen)
{
	*ppDecryptedData = (BYTE*)malloc(encryptedDataLen);
	ZeroMemory(*ppDecryptedData, encryptedDataLen);
	if (*ppDecryptedData == NULL)
	{
		printf("Memory allocation failed.\n");
		return FALSE;
	}

	memcpy(*ppDecryptedData, pEncryptedData, encryptedDataLen);
	*pDecryptedDataLen = encryptedDataLen;
	if (!CryptDecrypt(hKey, NULL, TRUE, 0, *ppDecryptedData, pDecryptedDataLen))
	{
		printf("CryptDecrypt failed: %d\n", GetLastError());
		free(*ppDecryptedData);
		return FALSE;
	}

	return TRUE;
}

6、测试和验证

? ? ? ? 上面三部分代码,大家如果放到一个文件里面,其实就可以开始编译验证了。单步调试即可。主要的验证方法,就是确认加密前和加密后的数据是否一致即可。当然,这个demo还有一个很大的不足,就是目前为止,生成的key没有导出来,每次都是重新创建。

? ? ? ? 实际应用中,对于生成的key,一般需要用CryptExportKey和CryptImportKey进行导出和导入处理一下。有兴趣的同学可以继续把这部分代码补充上,让整体的功能更加完善一点。

文章来源:https://blog.csdn.net/feixiaoxing/article/details/135566213
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。