AES 在 Qt 中的 StringSource 和 StringSink 函数中不能正常工作
AES not work properly in StringSource and StringSink functions in Qt
我在 Qt 中使用了 Crypto++ 库,因为在 CBC
中使用 AES
方法加密了一个字符串] 模式并使用 StringSource
和 StringSink
来定义 input
和 output
字符串参数。
首先,我从文件中读取所有字节("unicode"或"ASCII"编码),然后将其设置为StringSource
函数中的input
参数,然后设置作为输出(密文)的 string
(数据类型)的参数。只是我想得到一个字符串并用 "aes-cbc" 加密它并显示输出。
此外,我知道FileSource
和FileSink
是两个函数(由input
和output
流参数组成)用于将数据写入文件!但我想将文件内容作为输入字符串读取。
我的代码:
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();
}
现在我有以下问题:
当我读取一个紧凑的文件内容(例如900字节)并将其设置为StringSource
中的输入时,生成的密码将不完整(例如320字节)
strlen(cipher.c_str())
的输出与 "QMessageBox"
中的 cipher.size()
不同
我的代码真正工作 当我读取一些文件("unicode" 或 "ASCII"、"larg" 或 "little" 大小)并且有时工作不正确。不明白是什么原因造成的?
- 甚至,我直接设置了一些输入字符串(不是从文件中读取)并再次失败!
此致!
我可以是你的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 来确保机密性和真实性。
我在 Qt 中使用了 Crypto++ 库,因为在 CBC
中使用 AES
方法加密了一个字符串] 模式并使用 StringSource
和 StringSink
来定义 input
和 output
字符串参数。
首先,我从文件中读取所有字节("unicode"或"ASCII"编码),然后将其设置为StringSource
函数中的input
参数,然后设置作为输出(密文)的 string
(数据类型)的参数。只是我想得到一个字符串并用 "aes-cbc" 加密它并显示输出。
此外,我知道FileSource
和FileSink
是两个函数(由input
和output
流参数组成)用于将数据写入文件!但我想将文件内容作为输入字符串读取。
我的代码:
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();
}
现在我有以下问题:
当我读取一个紧凑的文件内容(例如900字节)并将其设置为
StringSource
中的输入时,生成的密码将不完整(例如320字节)strlen(cipher.c_str())
的输出与 "QMessageBox" 中的 我的代码真正工作 当我读取一些文件("unicode" 或 "ASCII"、"larg" 或 "little" 大小)并且有时工作不正确。不明白是什么原因造成的?
- 甚至,我直接设置了一些输入字符串(不是从文件中读取)并再次失败!
cipher.size()
不同
此致!
我可以是你的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 来确保机密性和真实性。