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

news2024/9/25 19:18:57

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱: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进行导出和导入处理一下。有兴趣的同学可以继续把这部分代码补充上,让整体的功能更加完善一点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1380122.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大模型开启应用时代 数钉科技一锤定音

叮叮叮叮&#xff01;数钉智造大模型&#xff0c;“定音”强势发布&#xff01; 随着科技的飞速发展&#xff0c;大模型技术已逐渐成为推动产业变革的核心力量。在这一浪潮中&#xff0c;数钉科技凭借深厚的技术积累和敏锐的市场洞察力&#xff0c;成功利用大模型技术搭建起智能…

银行接口测试学习笔记:接口测试从分析到设计!

一、接口测试流程 01\接口测试计划 制定:人员,工具/平台,脚本,时间,标准,输出接口测试计划文档 02\银行接口文档解析 ①.接口名称:说明接口的作用,不用测试 ②.接口地址:http开头,和URL一样,不用测试 ③.请求方式:post/get/delete/put, 当一个接口有多个方式的时候是需要进…

Leetcode202快乐数(java实现)

今天分享的题目是快乐数&#xff1a; 快乐数的定义如下&#xff1a; 快乐数&#xff08;Happy Number&#xff09;是指一个正整数&#xff0c;将其替换为各个位上数字的平方和&#xff0c;重复这个过程直到最后得到的结果为1&#xff0c;或者无限循环但不包含1。如果最终结果为…

金融疆界:在线支付系统渠道网关的创新设计(一)

这是《百图解码支付系统设计与实现》专栏系列文章中的第&#xff08;11.1&#xff09;篇。点击上方关注&#xff0c;深入了解支付系统的方方面面。 整个渠道网关的内容预计会分成5篇来讲&#xff1a;1&#xff09;定位、术语、概要设计。2&#xff09;领域模型、状态机设计。3…

小程序开发公司哪家好?哪家最好?

小程序具有轻量、聚焦、快捷等特点&#xff0c;这有别于 web 端类和移动端 app 类产品。 小程序的第一印象非常关键&#xff0c;因此对于首页设计&#xff0c;关键要加强注意力表达&#xff0c;给予用户尽可能直观的信息感知&#xff0c;加快建立其对于业务价值的兴趣&#xf…

linux环境安装docker

一、Docker是什么? 当我们开发一个应用程序时&#xff0c;通常需要配置和安装各种软件、库和依赖项。而这些环境配置可能会因为不同的操作系统或版本而存在差异&#xff0c;导致应用在不同环境中运行出现问题。 Docker就像是一个集装箱&#xff0c;可以将应用程序及其所有依…

重生奇迹mu敏弓加点攻略

1. 选择正确的属性点分配 在重生奇迹mu游戏中敏弓的属性点分配非常重要。建议将主要属性点分配在敏捷和力量上这样可以提高敏弓的攻击力和闪避能力。适当加点在体力和魔力上可以提高敏弓的生存能力和技能释放次数。不要忘记适当加点在智力上可以提高敏弓的技能威力和命中率。 …

用通俗易懂的方式讲解:图解 Transformer 架构

文章目录 用通俗易懂方式讲解系列1.导语2.正文开始现在我们开始“编码”从宏观视角看自注意力机制从微观视角看自注意力机制通过矩阵运算实现自注意力机制残差模块最终的线性变换和Softmax层训练部分总结损失函数再进一步 用通俗易懂方式讲解系列 用通俗易懂的方式讲解&#x…

机器学习第二十五周周报 ConvLSTM

文章目录 week 25 ConvLSTM摘要Abstract一、李宏毅机器学习二、文献阅读1. 题目2. abstract3. 网络架构3.1降水预报问题的建模3.2Convolutional LSTM3.3编码-预测结构 4. 文献解读4.1 Introduction4.2 创新点4.3 实验过程4.3.1Moving-MNIST Dataset4.3.2雷达回波数据集 4.4 结论…

浅谈Vue3中v-if与v-for优先级问题。

一、注意 在Vue3官方文档中&#xff0c;不推荐同时使用 v-if 和 v-for &#xff0c;因为这样二者的优先级不明显。 当它们同时存在于一个节点上时&#xff0c;v-if 比 v-for 的优先级更高。这意味着 v-if 的条件将无法访问到 v-for 作用域内定义的变量别名。 二、怎么解决 在外…

【数据分析】数据分析方法 | A/B测试与多变量分析

【数据分析】数据分析方法 | A/B测试与多变量分析 上一次与大家讨论了数据分析方法中的市场细分与同期群分析&#xff0c;此次仍然是对数据分析方法的讨论&#xff0c;讨论A/B测试与多变量分析的应用。 如果撇开统计性数据分析不谈&#xff0c;数据分析的最终目的是为了对具体…

神经网络学习小记录77——深入浅出Self-Attention自注意力机制与Transformer模块

神经网络学习小记录77——深入浅出Self-Attention自注意力机制与Transformer模块 学习前言代码下载Self-Attention自注意力机制详解一、Self-attention结构解析二、Self-attention的矩阵运算三、Multi-Head多头注意力机制 TransformerBlock的构建一、视觉部分的TransformerBloc…

10-skywalking告警

https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/backend-alarm.md 5.1&#xff1a;告警指标 ~$ vim /apps/apache-skywalking-apm-bin/config/oal/core.oal service_resp_time # 服务的响应时间 service_sla # 服务http请求成功率SLV&#xff0c;比…

Logstash配置详解

一、配置文件 Logstash配置文件位于Logstash安装目录下bin/logstash.conf 启动命令: logstash -f logstash.conf文件描述logstash.yml配置Logstash的yml。pipelines.yml包含在单个Logstash实例中运行多个管道的框架和说明。jvm.options配置Logstash的JVM&#xff0c;使用此文…

线程安全--互斥锁

文章目录 一.线程安全问题读取无效(脏)数据丢失更新线程安全的保证--操作的原子性 二.互斥锁及其实现原理互斥锁的实现原理pthread线程库提供的锁操作 三.死锁问题 一.线程安全问题 当多个线程并发地对同一个共享资源进行修改操作时,可能会引发数据读写错误(比如读取无效(脏)数…

[Flutter] extends、implements、mixin和 abstract、extension的使用介绍说明

类创建&#xff1a;abstract&#xff08;抽象类&#xff09;、extension&#xff08;扩展&#xff09; 1.abstract&#xff08;抽象类&#xff09; dart 抽象类主要用于定义标准&#xff0c;子类可以继承抽象类&#xff0c;也可以实现抽象类接口。抽象类通过abstract 关键字来…

NLP论文阅读记录 - 2023 | EXABSUM:一种新的文本摘要方法,用于生成提取和抽象摘要

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 EXABSUM: a new text summarization approach for generating ex…

PLC控制脉冲轴绝对位置往复运动(三菱FX系列简单状态机编程)

有关状态机的具体介绍,专栏有很多文章,大家可以通过下面的链接查看: https://rxxw-control.blog.csdn.net/article/details/125488089https://rxxw-control.blog.csdn.net/article/details/125488089三菱FX系列回原功能块介绍 https://rxxw-control.blog.csdn.net/article…

springboot注解@PropertySource作用

简介 PropertySource 是 Spring 框架中的一个注解&#xff0c;用于指定一个或多个属性文件&#xff08;通常是.properties文件&#xff09;这些文件包含了应用程序需要的配置信息。当你在 Spring 的配置类中使用此注解时&#xff0c;Spring 容器会加载这些属性文件&#xff0c…