QT AES对字符串和文件的加密解密
QT AES对字符串和文件的加密解密
在Github和优快云上找到过很多有关QT实现AES加密文件的博文,但是都没能解决我的问题。在各种踩坑,耗费一个星期之后,总算将这个问题搞清楚。本文将会详细介绍如何使用AES对称加密实现对字符串和文件的加密和解密,最后会奉献出亲测绝对可用的代码。
一、 AES加密算法介绍
很多博文介绍的QT自带的 base64 不能称为加密,它仅仅是一种任意二进制到文本字符串的编码方法。MD5、SHA等属于消息摘要算法,主要用于一致性验证,防止被篡改,像密码的加密是可以采用此类解密算法。它是没有密匙,也是不可逆的加密算法,显然不能用于对文件的加密和解密。
能用于加密和解密的算法分为对称加密和非对称加密两类。对称加密包括AES、DES等算法,非对称加密包含RSA、DSA、ECC等加密算法,本文讨论的AES加密算法就是一种堆成加密算法,其加密和解密的秘钥是相同的。
自己当时捯饬了半天的 base64 和 MD5,最后才发现他们并不能实现自己对文件加密和解密的需求,故特此解释一下。要是想深入了解AES加密的原理,可以查看下方链接。
AES加密算法的详细介绍与实现
二、 用AES加密算法实现对字符串的加密和解密
代码的注释是及其详细的,有不懂的地方可以多看几遍注释
1. 加密方法:OnAesEncrypt(LPVOID InBuffer,DWORD InLength,LPVOID OutBuffer)
//<---加密方法---->
DWORD AesTools::OnAesEncrypt(LPVOID InBuffer,DWORD InLength,LPVOID OutBuffer)
{
//DWORD占4个字节
DWORD OutLength=0,ExtraBytes = 0;
if (m_lpAes==NULL||OutBuffer==NULL)
{
return 0;
}
//InBuffer是一个char类型的数组,lpCurInBuff指针指向的是InBuffer char数组的第一个元素的地址
UCHAR *lpCurInBuff=(UCHAR *)InBuffer;
//加密后的数据往OutBuffer中写入时,从第16个字节开始写。前面空出16个字节,用于存放密文大小和额外加密的字节个数,只用到8个字节,但为了保证字节总数是16的倍数,故预留了16个字节
UCHAR *lpCurOutBuff=(UCHAR *)OutBuffer+16;
long blocknum=InLength/16;
long leftnum=InLength%16;
for(long i=0;i<blocknum;i++)
{
//加密时,传入的数组必须时16个字节的
m_lpAes->Cipher(lpCurInBuff,lpCurOutBuff);
//每次加密16个字节,循环直至所有字节均被加密
lpCurInBuff+=16;
lpCurOutBuff+=16;
OutLength+=16;
}
//当传入的密文的字节总数不是16的倍数时,会多余出leftnum 个字节。
//此时,需要添加16-leftnum 个字节到mingwen中。则加密得到的密文,会多出16-leftnum 个字节。
//这16-leftnum 个字节并不是mingwen里存在的
if(leftnum)
{
UCHAR inbuff[16];
memset(inbuff,'X',16);
//经过上面的for循环,此时lpCurInBuff指针指向InBuffer数组的sizeof(InBuffer)-leftnum 位置处
memcpy(inbuff,lpCurInBuff,leftnum);
//此次解密,实际上是多加密了16-leftnum 个字节
m_lpAes->Cipher(inbuff,lpCurOutBuff);
lpCurOutBuff+=16;
OutLength+=16;
}
UCHAR *bytesSize=(UCHAR *)OutBuffer;
UCHAR *extraBytesSize = (UCHAR *)(OutBuffer+4);
//多加密的字节个数
ExtraBytes = (16-leftnum)%16;
//将OutLength的地址复制给bytesSize的前4个字节。即将加密后的密文大小存放在miwen的前四个字节中
memcpy(bytesSize,&OutLength,4);
//将多加密的字节个数存放在第4-8个字节中
memcpy(extraBytesSize,&ExtraBytes,4);
//返回的OutLength只包括密文长度,不包括outBuffer中预留用来存放outBuffer字节个数和额外多加密的字节个数的16字节。
//即OutLength = sizeof(OutBuffer)-16
return OutLength;
}
函数名称:OnAesEncrypt
函数描述:用AES加密算法加密数据
调用参数:(具体使用见后面的调用测试代码)
- LPVOID InBuffer:加密的明文,传参数时可以将char mingwen[]数组强转为LPVOID 类型。
- DWORD InLength,:明文的实际大小
- LPVOID OutBuffer:加密之后的密文
返回数值:加密后的数据大小 ,错误返回值 0
2. 解密方法:OnAesUncrypt(LPVOID InBuffer,DWORD InLength,LPVOID OutBuffer)
DWORD AesTools: