AES 在 Qt 中的 StringSource 和 StringSink 函数中不能正常工作

AES not work properly in StringSource and StringSink functions in Qt

我在 Qt 中使用了 Crypto++ 库,因为在 CBC 中使用 AES 方法加密了一个字符串] 模式并使用 StringSourceStringSink 来定义 inputoutput 字符串参数。

首先,我从文件中读取所有字节("unicode"或"ASCII"编码),然后将其设置为StringSource函数中的input参数,然后设置作为输出(密文)的 string(数据类型)的参数。只是我想得到一个字符串并用 "aes-cbc" 加密它并显示输出。

此外,我知道FileSourceFileSink是两个函数(由inputoutput流参数组成)用于将数据写入文件!但我想将文件内容作为输入字符串读取。

我的代码:

void Widget::onEncryptButton()
{
    QByteArray key = "qwertyuiopasdfgh";
    QByteArray iv = "wertyuiopasdfghj"
    QByteArray plain;
    string cipher;

    QFile fi("/home/msi/Desktop/input.txt");
    QFile fo("/home/msi/Desktop/output.enc");

    fi.open(QFile::ReadOnly);
    fo.open(QFile::WriteOnly);
    plain = fi.readAll();

    AESEncryption aese((byte*)key.constData(), AES::DEFAULT_KEYLENGTH);    // default is 16
    CBC_Mode_ExternalCipher::Encryption encryptor(aese, (byte*)iv.constData());
    StringSource(plain, true, new StreamTransformationFilter(encryptor, new StringSink(cipher)));

    QMessageBox::information(this, "", QString("%1, %2").arg(strlen(cipher.c_str())).arg(cipher.size()));    // just for viewing cipher length

    fo.write(cipher.c_str());
    fi.close();
    fo.close();
}

现在我有以下问题:

此致!

我可以是你的plain,如果它包含'\0'。尝试同时传递数据和长度:

StringSource((byte*)plain.constData(), plain.size(), true, new StreamTransformationFilter(encryptor, new StringSink(cipher)));

我替换下面的语句:

StringSource((byte*)plain.constData(), plain.size(), true, new StreamTransformationFilter(encryptor, new StringSink(cipher)));

随着波纹管:

StringSource(plain, true, new StreamTransformationFilter(encryptor, new StringSink(cipher)));

然后,我重新编译程序,问题依旧!

暂时去掉明文中的所有'\'字符,重新编译,然后输出的密文如"QMessageBox"和cipher.size()真实声明。

然后替换

fo.write(cipher.c_str(), cipher.size());

与:

fo.write(cipher.c_str());

我做这些加密和解密部分的说明。

我会考虑修改函数:

// Improve this in real life
QByteArray key = "qwertyuiopasdfgh";
QByteArray iv = "wertyuiopasdfghj"

std::string infile("/home/msi/Desktop/input.txt");
std::string outfile("/home/msi/Desktop/output.enc");

CBC_Mode<AES>::Encryption encryptor(key.constData(), key.size(), iv.constData());
FileSource fs(infile.c_str(), true, new StreamTransformationFilter(encryptor, new FileSink(outfile.c_str())));

使用 FileSource and FileSink 可以避免尝试解释字符集下的数据时出现的问题。它还节省了额外的副本,并且对没有大量 RAM 的移动设备和物联网小工具更友好。

您也可以考虑使用 Authenticated Encryption mode 来确保机密性和真实性。