问题
I want to make program that encrypts (later decrypts) user inputted string. Here is beginning for encryption:
QString getData = ui->text->toPlainText(); //Data to process
std::string output; //Result will be Base32 encoded string, so std::string is fine.
Now, I have to convert QString
to char*
or std::string
so it can be accepted with Crypto++. I thought that QByteArray
would be fine, as it has .data()
function, which returns char *
. (getData
always 17 or more bytes long: CryptoPP requires at least 17 bytes for AES encryption).
So, I have used following code:
QByteArray data;
data.append(getData);
//Creating key and iv:
//Creating AES encryptor:
//Encrypting AES and Base32:
CryptoPP::StringSource ss((const byte*)data.data(), data.size() , true,
new CryptoPP::StreamTransformationFilter( Encryptor,
new CryptoPP::Base32Encoder(
new CryptoPP::StringSink(output)
) // Base32Encoder
) // StreamTransformationFilter
); // StringSource
ui->text->clear();
getData = output.c_str();
ui->text->setText(getData);
Everything is seems to be fine. But I want it to support non-ASCII characters (I mean russian, lithuanian etc.). After decryption they change to ?
. How could I fix this? I understand, that std::string
doesn`t support them.
EDIT: Here is updated code:
Encryption:
QString getData = ui->text->toPlainText(); //Data to process
std::string output;
QByteArray data = getData.toUtf8();
//Creating key and iv: <..>
//Creating AES encryptor: <..>
//Encrypting AES and Base32:
CryptoPP::StringSource ss((const byte*) data.data(),getData.size()*2, true,
new CryptoPP::StreamTransformationFilter( Encryptor,
new CryptoPP::Base32Encoder(
new CryptoPP::StringSink(output)
) // Base32Encoder
) // StreamTransformationFilter
); // StringSource
ui->text->clear();
getData = output.c_str();
ui->text->setText(getData);
And decryption:
QString getData = ui->text->toPlainText();
QByteArray data;
data.append(getData);
std::string output;
//Creating key and iv:
byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ],
iv[ CryptoPP::AES::BLOCKSIZE ];
//Memsetting them: (randomization needed)
::memset( key, 0x01, CryptoPP::AES::DEFAULT_KEYLENGTH );
::memset( iv, 0x01, CryptoPP::AES::BLOCKSIZE );
//Creating AES decryptor:
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption decryptor( key, sizeof(key), iv );
//Decrypting Base32 and AES
CryptoPP::StringSource ss((const byte*) data.data(), data.size(), true,
new CryptoPP::Base32Decoder(
new CryptoPP::StreamTransformationFilter( Decryptor,
new CryptoPP::StringSink(output)
) // StreamTransformationFilter
) // Base32Encoder
); // StringSource
ui->text->clear();
getData = QString::fromUtf8(output.c_str());
ui->text->setText(getData);
Does it have any bugs I have missed?
回答1:
I think you're losing data when converting from QString to QByteArray. Try this:
QByteArray data = getData.toUtf8();
...
getData = QString::fromUtf8( output.c_str() );
回答2:
Use reinterpret_cast<byte*>(QString::data())
instead. Don't try to actually do code page conversion here -- AES does not care. Use an ArraySink instead of a StringSink.
Keep in mind that the size of the actual QString::data() buffer is twice the number of characters contained there, because it uses UTF-16.
来源:https://stackoverflow.com/questions/3398304/converting-qstring-qchar-to-be-accepted-with-crypto