错误的解密错误OpenSSL C ++和QT AES 256 CBC

时间:2018-08-14 12:45:44

标签: c++ qt openssl

我正在尝试向使用QT和C ++构建的个人项目添加纯文本加密/解密(AES 256 CBC)功能。我正在使用OpenSSL v1.1.1。我遵循了一些指南,并建立了一个处理加密和解密的类。加密似乎可以正常工作。但是解密功能有时会抛出error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

这有效:

sample text here....

这些不是(。=换行符):

i。

sample text here...
.
.
.
.
.

ii。

sample text here... sample text here...

我是QT,C ++和OpenSSL的新手,所以我不知道如何解决此问题。

我的课:

#define KEYSIZE 32
#define IVSIZE 32
#define BLOCKSIZE 256
#define SALTSIZE 8

QByteArray Encryptor::randBytes(int size) {
    unsigned char array[size];
    RAND_bytes(array, size);
    QByteArray output = QByteArray(reinterpret_cast<char*> (array), size);
    return output;
}

QByteArray Encryptor::encrypt(QByteArray passphrase, QByteArray &content) {
    QByteArray msalt = randBytes(SALTSIZE);
    int rounds = 1;
    unsigned char key[KEYSIZE];
    unsigned char iv[IVSIZE];
    const unsigned char *password = (const unsigned char*) passphrase.constData();
    const unsigned char *salt = (const unsigned char*) msalt.constData();

    int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, password, passphrase.length(), rounds, key, iv);

    if (i != KEYSIZE) {
        qCritical() << "EVP_BytesToKey() -- " << ERR_error_string(ERR_get_error(), NULL);
        return QByteArray();
    }

    EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(en);

    if (!EVP_EncryptInit_ex(en, EVP_aes_256_cbc(), NULL, key, iv)) {
        qCritical() << "EVP_EncryptInit_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
        return QByteArray();
    }

    char *input = content.data();
    char *out;
    int length = content.size();
    int cLength = length + AES_BLOCK_SIZE;
    int fLength = 0;
    unsigned char *cipherText = (unsigned char*) malloc(cLength);

    if (!EVP_EncryptInit_ex(en, NULL, NULL, NULL, NULL)) {
        qCritical() << "EVP_EncryptInit_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
        return QByteArray();
    }

    if (!EVP_EncryptUpdate(en, cipherText, &cLength, (unsigned char*) input, length)) {
        qCritical() << "EVP_EncryptUpdate() -- " << ERR_error_string(ERR_get_error(), NULL);
        free(cipherText);
        return QByteArray();
    }

    if (!EVP_EncryptFinal(en, cipherText + cLength, &fLength)) {
        qCritical() << "EVP_EncryptFinal() -- " << ERR_error_string(ERR_get_error(), NULL);
        free(cipherText);
        return QByteArray();
    }

    length = cLength + fLength;
    out = (char*) cipherText;
    EVP_CIPHER_CTX_cipher(en);

    free(cipherText);

    QByteArray output;
    output.append("Salted__");
    output.append(msalt);
    output.append(out, length);

    return output;
}

QByteArray Encryptor::decrypt(QByteArray passphrase, QByteArray &content) {
    QByteArray msalt;

    if (QString(content.mid(0, 8)) != "Salted__") {
        qCritical() << "can not extrect the salt...";
        return QByteArray();
    }

    msalt = content.mid(8, 8);
    content = content.mid(16);

    int rounds = 1;
    unsigned char key[KEYSIZE];
    unsigned char iv[IVSIZE];
    const unsigned char *password = (const unsigned char*) passphrase.constData();
    const unsigned char *salt = (const unsigned char*) msalt.constData();

    int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, password, passphrase.length(), rounds, key, iv);

    if (i != KEYSIZE) {
        qCritical() << "EVP_BytesToKey() -- " << ERR_error_string(ERR_get_error(), NULL);
        return QByteArray();
    }

    EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(de);

    if (!EVP_DecryptInit_ex(de, EVP_aes_256_cbc(), NULL, key, iv)) {
        qCritical() << "EVP_DecryptInit_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
        return QByteArray();
    }

    char *input = content.data();
    int length = content.size();
    int pLength = length;
    int fLength = 0;
    unsigned char *plainText = (unsigned char*) malloc(pLength + AES_BLOCK_SIZE);

    if (!EVP_DecryptUpdate(de, plainText, &pLength, (unsigned char*) input, length)) {
        qCritical() << "EVP_DecryptUpdate() -- " << ERR_error_string(ERR_get_error(), NULL);
        free(plainText);
        return QByteArray();
    }

    if (!EVP_DecryptFinal_ex(de, plainText + pLength, &fLength)) {
        qCritical() << "EVP_DecryptFinal_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
        free(plainText);
        return QByteArray();
    }

    length = pLength + fLength;
    EVP_CIPHER_CTX_cleanup(de);

    QByteArray output = QByteArray(reinterpret_cast<char*> (plainText), length);
    free(plainText);

    return output;
}

0 个答案:

没有答案