QT版本基于OpenSSL3的AES加密算法

项目地址Gitee地址

主要代码
#ifndef QAES_H
#define QAES_H

#include <QByteArray>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <QString>
#include <QDebug>
#include <QScopedPointer>

class QAES
{
public:

    struct ScopedPointerCipherCtxDeleter
    {
        static inline void cleanup(EVP_CIPHER_CTX *pointer)
        {
            EVP_CIPHER_CTX_free(pointer);
        }
    };

    // 解密函数,失败返回空
    static QByteArray decrypt(QByteArray cyphertext, QByteArray key, QByteArray iv);

    // 加密函数,失败返回空
    static QByteArray encrypt(QByteArray plaintext, QByteArray key, QByteArray iv);

    // 获取最后一次错误信息
    static QString GetLastError();
};

#endif // QAES_H
#include "qaes.h"


QByteArray QAES::decrypt(QByteArray cyphertext, QByteArray key, QByteArray iv)
{
    ERR_clear_error();
    // 检查密钥合法性(只能是16、24、32字节)
    Q_ASSERT(key.size() == 32 );
    Q_ASSERT(iv.size() == 16);

    QByteArray plaintext;
    QScopedPointer <EVP_CIPHER_CTX , ScopedPointerCipherCtxDeleter> ctx(EVP_CIPHER_CTX_new());

    if (!EVP_DecryptInit_ex(ctx.data(), EVP_aes_256_cbc(), NULL, (unsigned char *)key.data(), (unsigned char *)iv.data()))
    {
        plaintext.clear();
        return plaintext;
    }
    if (!EVP_CIPHER_CTX_set_padding(ctx.data(), EVP_PADDING_PKCS7))
    {
        plaintext.clear();
        return plaintext;
    }
    int outlen = 0;
    plaintext.resize(cyphertext.size());
    if (!EVP_DecryptUpdate(ctx.data(), (unsigned char *)plaintext.data(), &outlen, (unsigned char *)cyphertext.data(), cyphertext.size()))
    {
        plaintext.clear();
        return plaintext;
    }
    int tmplen = 0;
    if (!EVP_DecryptFinal_ex(ctx.data(), (unsigned char *)plaintext.data() + outlen, &tmplen))
    {
        plaintext.clear();
        return plaintext;
    }
    return plaintext.left(outlen + tmplen);
}


QByteArray QAES::encrypt(QByteArray plaintext, QByteArray key, QByteArray iv)
{
    ERR_clear_error();
    // 检查密钥合法性(只能是16、24、32字节)
    Q_ASSERT(key.size() == 32 );
    Q_ASSERT(iv.size() == 16);


    QByteArray cyphertext;
    QScopedPointer <EVP_CIPHER_CTX , ScopedPointerCipherCtxDeleter> ctx(EVP_CIPHER_CTX_new());

    if (!EVP_EncryptInit_ex(ctx.data(), EVP_aes_256_cbc(), NULL, (unsigned char*)key.data(), (unsigned char*)iv.data()))
    {
        cyphertext.clear();
        return cyphertext;
    }
    if (!EVP_CIPHER_CTX_set_padding(ctx.data(), EVP_PADDING_PKCS7))
    {
        cyphertext.clear();
        return cyphertext;
    }
    int outlen = 0;
    cyphertext.resize(plaintext.size() + 16);
    if (!EVP_EncryptUpdate(ctx.data(), (unsigned char *)cyphertext.data(), &outlen, (const unsigned char *)plaintext.data(), plaintext.size()))
    {
        cyphertext.clear();
        return cyphertext;
    }
    int tmplen = 0;
    if (!EVP_EncryptFinal_ex(ctx.data(), (unsigned char *)cyphertext.data() + outlen, &tmplen))
    {
        cyphertext.clear();
        return cyphertext;
    }

    return cyphertext.left(outlen + tmplen);
}

QString QAES::GetLastError()
{
    unsigned long lastError = ERR_peek_last_error();
    if (lastError == 0) {
        return "";
    }
    char errorString[256];
    ERR_error_string_n(lastError, errorString, sizeof(errorString));
    return errorString;
}
使用方法
QString inputStr("The Advanced Encryption Standard (AES), also known by its original name Rijndael "
                     "is a specification for the encryption of electronic data established by the U.S. "
                    "National Institute of Standards and Technology (NIST) in 2001");
QString key("your-string-key");
QString iv("your-IV-vector");

QByteArray hashKey = QCryptographicHash::hash(key.toLocal8Bit(), QCryptographicHash::Sha256);
QByteArray hashIV = QCryptographicHash::hash(iv.toLocal8Bit(), QCryptographicHash::Md5);

qDebug() << "原始数据" << inputStr.toUtf8();
QByteArray encodeText = QAES::encrypt(inputStr.toUtf8(), hashKey, hashIV);
qDebug() << "加密数据"<< encodeText << QAES::GetLastError();
QByteArray decodeText = QAES::decrypt(encodeText, hashKey, hashIV);
qDebug() << "解密数据"<< decodeText<< QAES::GetLastError();
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值