对称加密:指的是加密方和解密方使用的是同一个密钥

非对称加密:非对称加密方式解决了对称加密的缺陷,它的加密和解密密钥是不同的,比如对一组数字加密,我们可以用公钥对其加密,然后我们想要将其还原,就必须用私钥进行解密,公钥和私钥是配对使用的,常见的非对称加密算法有:

公钥加密 私钥解密

RSA:既可以用来加密解密,又可以用来实现用户认证


非对称加密长度通常有512,1024,2048,4096位,最常用的就是2048位,长度固然可以增加安全性但是需要花费很长时间来进行加密/解密,和对称加密相比,加密/解密的时间差不多是对称加密的1000倍,所以我们通常用其作为用户认证,用对称加密来实现数据的加密/解密

ps:加密长度512位可以暴力破解


单项加密:单向加密就是用来计算一段数据的特征码的,为了防止用户通过“暴力破解”的方式解密,所以单向加密一般具有“雪崩效应”就是说:只要被加密内容有一点点的不同,加密所得结果就会有很大的变化。单项加密还有一个特点就是无论被加密的内容多长/短,加密的结果(就是提取特征码)是定长的,用途:用于验证数据的完整性,常用的单项加密算法

MD5:这种加密算法固定长度为128位

SHA1:这种加密算法固定长度是160位



本期通过Qt QCryptographicHash::Md5 对磁盘上的文件进行单项加密


效果展示:


对2.86 GB (3,076,476,328 字节)的文件在线程中进行单项加密,不卡主界面,加密进度通过信号/槽返回给主界面显示。


大量数据的加密

void addData(const QByteArray &data)

示例:

QCryptographicHash hash(QCryptographicHash::Md5);
while(!file.atEnd())
{
QByteArray content = file.read(1024*1024); /*读取1M数据*/
hash.addData(content); /*多次计算*/
}
QByteArray md5 = hash.result().toHex(); /*MD5:这种加密算法固定长度为128位,32字节*/

Md5单项加密对象设计

signals:

signals:
void sendMd5CheckSumSignal(QByteArray); //反馈md5值到界面
void sendProgressBarSignal(int, int); //反馈进度到界面 以生成进度条

public slots:

public slots:
void getMd5CheckSumSlot(const QString &filePath); /*Md5单项加密计算槽函数*/

md5check.h

#ifndef MD5CHECK_H
#define MD5CHECK_H

#include <QObject>
#include <QCryptographicHash>
#include <QFile>
#include <QFileInfo>
#include <QDebug>

class Md5Check : public QObject
{
Q_OBJECT
public:
explicit Md5Check(QObject *parent = nullptr);

signals:
void sendMd5CheckSumSignal(QByteArray); //反馈md5值到界面
void sendProgressBarSignal(int, int); //反馈进度到界面 以生成进度条
//已经处理的数据量 待处理的总量

public slots:
void getMd5CheckSumSlot(const QString &filePath);
};

#endif // MD5CHECK_H

md5check.cpp

#include "md5check.h"

Md5Check::Md5Check(QObject *parent) : QObject(parent){}

void Md5Check::getMd5CheckSumSlot(const QString &filePath)
{
QFile file(filePath);
QByteArray md5Result;
QFileInfo md5FileInfo;
md5FileInfo = QFileInfo(filePath); /*获取文件信息,考虑到文件过大*/

int totalSize = md5FileInfo.size()/(1024*1024); /* 把Byte字节转换成M兆 */
if(md5FileInfo.size()%(1024*1024)>0)
totalSize+=1; /* 多余补一 */
int currentSize = 0; /*当前进度,读取的M兆数*/

if(file.open(QIODevice::ReadOnly))
{
QCryptographicHash hash(QCryptographicHash::Md5);
while (!file.atEnd()) { //读取文件直到读物完整
QByteArray content = file.read(1024*1024); /*每次读取一兆M*/
hash.addData(content); /*分段进程MD5累加*/
currentSize++; /*当前进度,进度加一*/
emit sendProgressBarSignal(totalSize,currentSize); /*传送百分比信号*/
}
md5Result = hash.result().toHex(); /*MD5值为32位的十六进制数*/
emit sendMd5CheckSumSignal(md5Result); /*发送MD5结果*/
file.close();
}
}

线程处理IO操作

定义Md5Check对象以及处理线程

QThread md5Thread;          //线程
Md5Check mMd5CheckSum;

将对象移至线程

mMd5CheckSum.moveToThread(&md5Thread);      /*从一个object 移动到 一个thread*/
md5Thread.start(); /*开启线程*/

关联信号与槽

/* 关联MD5计算槽函数 让Md5Check对象开始计算MD5值 */
connect(this,SIGNAL(checkMd5SumSignal(QString)),&mMd5CheckSum,SLOT(getMd5CheckSumSlot(QString)));
/*关联MD5结果返回信号,将MD5计算结果传递给Widget定义的槽函数recvMd5CheckSumSlot*/
connect(&mMd5CheckSum, SIGNAL(sendMd5CheckSumSignal(QByteArray)),this, SLOT(recvMd5CheckSumSlot(QByteArray)));
/*关联MD5计算进度,将进度返回给Widget定义的槽函数recvProgressBarSlot*/
connect(&mMd5CheckSum, SIGNAL(sendProgressBarSignal(int,int)),this, SLOT(recvProgressBarSlot(int,int)));

开启md5单项加密任务

emit checkMd5SumSignal(md5Filename); /*将打开的文件路径通过信号传递给Md5Check对象*/

项目已同步至仓库,阅读全文可转跳

End



本文分享自微信公众号 - 编程学习基地(LearnBase)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

09-08 08:40