目的
加解密是非常重要的功能,尤其在现在互联网上,如果不加密,信息很容易泄露。
下面就以实例实现这一个功能:
关于AES的介绍
Aes就是一种高级加解密功能。
AES ( 高级加密标准 )是 美国联邦政府 采纳的对称加密标准,用于替代 DES ( 数据加密标准 )。
该标准由 比利时 密码学家 Joan Daemen 和 Vincent Rijmen 设计,采用置换-组合架构,支持128、192、256位密钥长度。
核心特性:
安全性:采用128位加密技术时,蛮力攻击破解需极长时间。
灵活性:支持三种密钥长度(128/192/256位),适应不同安全需求。
效率:加密轮数随密钥长度变化(如AES-128需10轮),软件和硬件实现效率高。
加密流程:
分组处理:明文按128位分组,每个分组独立加密。
轮函数:每轮包含AddRoundKey(密钥加)、SubBytes(字节替换)、ShiftRows(行移位)、MixColumns(列混合)四个步骤,最后一轮仅前三个步骤。
密钥调度:通过复杂算法生成子密钥,与明文分组逐轮结合。
应用场景
广泛应用于 微信小程序 、 网络通信 等领域,需注意密钥传输需通过非对称加密保护。
关于CryptoPP
(Crypto++)是一个开源的C++密码学库,提供了 AES 加密算法的实现。以下是关于CryptoPP中AES加密算法的详细说明:
AES加密算法特点
AES是一种对称加密算法,使用相同的密钥进行加密和解密。其核心特点包括:
分组长度固定:标准分组长度为128位(16字节)。
密钥长度可选:支持128、192、256位密钥长度,不同密钥长度对应不同轮数(10/12/14轮)。
加密模式:包括 CBC 、 CFB 、 OFB 、 ECB 四种模式,其中ECB模式无需向量参数,安全性较低。
加密与解密步骤
加密流程
分块处理:将明文分成128位的数据块。
初始轮密钥加密:用初始密钥对数据块进行混淆操作。
多轮加密:通过 SubBytes 、 ShiftRows 、 MixColumns 等操作对数据块进行混淆和扩散。
最终轮:省略MixColumns操作,生成密文。
解密流程
初始轮密钥解密:用初始密钥对密文进行逆混淆操作。
多轮解密:通过逆SubBytes、逆ShiftRows、逆MixColumns等操作恢复明文。
为什么选择cryptopp密码库:
在Qt开发中,选择加密库需根据具体需求判断:
Crypto++(CryptoPP)
优势:支持对称加密(如AES)、非对称加密(如RSA)、哈希算法等,提供多种加密模式(ECB、CBC、CFB、OFB)。
不足:安装依赖复杂,需手动配置环境(如sudo apt-get install libcrypto++),且文档和社区支持相对较少。
个人建议:安装时,没有感觉到依赖复杂,直接用编译好的库就可以了,没有什么复杂的
OpenSSL
优势:开源库,支持SSL/TLS协议,提供对称加密(如AES)、非对称加密(如RSA)及证书管理功能,与Qt集成方便。
不足:功能相对单一,主要聚焦于网络加密,对文件加密等场景支持较弱。
个人建议:OpenSSL的函数用法,函数名比较不友好,所就没有用它。
Qt-AES
优势:轻量级加密类,原生支持Qt框架,支持128/192/256位AES密钥长度及多种加密模式(ECB、CBC、CFB、OFB),提供硬件加速支持。
不足:仅支持AES加密,功能范围较窄。
个人建议:在使用时,其不能在window上使用,只能在Linux上使用,但我是在windows上用的,所以就没有选择Qt-AES,其用了ARM汇编,所以不能适配windows。
推荐选择
网络通信或需要SSL/TLS协议:优先使用OpenSSL。
文件加密或需要多种加密算法:优先考虑Crypto++。
轻量化需求且仅需AES加密:选用Qt-AES。
情况
下载cryptopp库链接
https://github.com/weidai11/cryptopp/tree/CRYPTOPP_8_9_0
实例效果
先看看效果吧,哈哈!
动态效果:
AES加解密
静态效果:
通过这一个程序,你可以发一些加密信息,对端再通过这一个软件解开,还是挺实用的。
实例代码
加密函数
// AES加密函数
QString AesUtil::aesEncrypt(const QString& plaintext, const QString& key, const QString& iv) {
try {
// 转换输入参数为CryptoPP需要的格式
string plain = plaintext.toStdString();
string keyStr = key.toStdString();
string ivStr = iv.toStdString();
// 设置加密模式和参数
CBC_Mode<AES>::Encryption encryption;
encryption.SetKeyWithIV((byte*)keyStr.data(), keyStr.size(), (byte*)ivStr.data());
// 执行加密
string ciphertext;
StringSource(plain, true,
new StreamTransformationFilter(encryption,
new StringSink(ciphertext)
)
);
// 将二进制密文转换为十六进制字符串便于显示和传输
string encoded;
StringSource(ciphertext, true,
new HexEncoder(
new StringSink(encoded)
)
);
return QString::fromStdString(encoded);
}
catch (const Exception& e) {
qDebug() << "加密错误:" << e.what();
return "";
}
}
上面的new 对象为什么没有手动释放,是因为StringSource函数的第二个参数为true时,这个参数的生命周期由StringSource函数进行管理,它在执行完成之后,对参数进行释放,这也是一种内存管理的模式,下面代码也是这样的。
解密函数
// AES解密函数
QString AesUtil::aesDecrypt(const QString& ciphertext, const QString& key, const QString& iv) {
try {
// 转换输入参数为CryptoPP需要的格式
string encoded = ciphertext.toStdString();
string keyStr = key.toStdString();
string ivStr = iv.toStdString();
// 将十六进制字符串转换回二进制
string decoded;
StringSource(encoded, true,
new HexDecoder(
new StringSink(decoded)
)
);
// 设置解密模式和参数
CBC_Mode<AES>::Decryption decryption;
decryption.SetKeyWithIV((byte*)keyStr.data(), keyStr.size(), (byte*)ivStr.data());
// 执行解密
string recovered;
StringSource(decoded, true,
new StreamTransformationFilter(decryption,
new StringSink(recovered)
)
);
return QString::fromStdString(recovered);
}
catch (const Exception& e) {
qDebug() << "解密错误:" << e.what();
return "";
}
}
事件函数:
void AesWidget::on_btnEncrypt_clicked()
{
qDebug("enter function AesWidget::on_btnEncrypt_clicked");
QString originText = m_editOriginText->toPlainText();
QString keyText = m_editKey->text();
if (keyText.length() != 16)
{
QMessageBox::information(this, "提示信息", "密钥必须是16位");
return;
}
QString encryText = m_aesUtil->aesEncrypt(originText, keyText, m_iv);
qDebug() << "encryText.toLocal8Bit().toHex() = " << encryText.toLocal8Bit().toHex();
qDebug() << "encryText.toUtf8().toHex() = " << encryText.toUtf8().toHex();
QString base64EncryText = m_aesUtil->convertOriginToBase64(encryText);
m_editEncryptDisplay->setPlainText(base64EncryText);
qDebug("exit function AesWidget::on_btnEncrypt_clicked");
}
void AesWidget::on_btnDecrypt_clicked()
{
qDebug("enter function AesWidget::on_btnDecrypt_clicked");
QString encryptText = m_editEncryptDisplay->toPlainText();
qDebug() << "encryText.toLocal8Bit().toHex() = " << encryptText.toLocal8Bit().toHex();
qDebug() << "encryText.toUtf8().toHex() = " << encryptText.toUtf8().toHex();
qDebug() << "encryText = " << encryptText;
QString keyText = m_editKey->text();
QString originEncryptText = m_aesUtil->convertBase64ToOrigin(encryptText);
QString decryText = m_aesUtil->aesDecrypt(originEncryptText, keyText, m_iv);
m_editDecryptionDisplay->setPlainText(decryText);
qDebug("exit function AesWidget::on_btnDecrypt_clicked");
}
AES的详细介绍
AES(Advanced Encryption Standard,高级加密标准) 是目前广泛使用的对称加密算法之一,它是对称加密的标准之一,用于加密和解密数据。AES被设计用于替代早期的DES(数据加密标准),并且在多个领域中得到广泛应用,如政府、金融、通信等。它具有高效性和安全性,能够保护数据的机密性。
一、AES的基本概念
1.对称加密
对称加密算法使用相同的密钥来加密和解密数据,这意味着加密方和解密方必须共享相同的密钥。
2.密钥长度
AES使用的密钥长度决定了算法的安全性和处理的复杂度,密钥越长,安全性越高,但加解密的速度可能会变慢。
AES支持三种不同的密钥长度:
128位密钥:即16字节
192位密钥:即24字节
256位密钥:即32字节
3.加密块大小
AES是一个块加密算法,它将数据分成固定大小的块进行加密。
AES的块大小始终是128位(16字节),与密钥长度无关。
4.加密模式
AES可以配合不同的加密模式工作。
常见的加密模式有:
(1)ECB(电子密码本模式)
每个明文块单独加密,但容易受到“模式攻击”(Pattern attacks),不建议使用。
(2)CBC(密码分组链接模式)
每个明文块与前一个密文块进行异或后再加密,增加了安全性。
(3)CFB(加密反馈模式)
是一个流加密模式,适用于加密长度未知的数据流。
(4)OFB(输出反馈模式)
类似于CFB,但更适合实时流数据的加密。
(5)CTR(计数器模式)
通过将计数器值与密钥进行加密来生成伪随机流,然后与明文进行异或操作。
二、AES算法的安全性
AES的安全性来自其复杂的数学结构和较长的密钥长度。
随着计算能力的提升,较短的密钥(如128位)可能不再足够安全,而256位密钥则被认为是非常安全的。
AES-256的抗攻击能力是非常强的,几乎不可能通过暴力破解来获得密钥。
三、总结
AES作为一种对称加密算法,以其高效性和安全性得到了广泛应用。其核心操作是将明文数据分块并进行多轮的替代、移位和变换,使得加密后的数据看起来非常随机且难以破解。AES的灵活性体现在支持不同的密钥长度和加密模式,同时它的安全性也得到了广泛的认可,适用于许多需要保密性的场合。
实例下载链接
https://download.csdn.net/download/maokexu123/91847883
总结
在Ase加解密过程中,加解密,直接调用函数就可以了,但加解密后的二进制数据,并不容易转换与存储,所以需要转换成十六进制的字符串,这样就容易转换了,这是简单的一步,却是非常重要的一步,最后以图说明: