AES-шифрование на QStrings, libcrypto++

У меня есть следующий фрагмент кода, который шифрует и дешифрует сообщение.

QString AesUtils::encrypt(QString message, QString aesKey)
{
    string plain = message.toStdString();
    qDebug() << "Encrypt" << plain.data() << " " << plain.size();
    string ciphertext;
    // Hex decode symmetric key:
    HexDecoder decoder;
    string stdAesKey = aesKey.toStdString();
    decoder.Put((byte*)stdAesKey.data(), aesKey.size());
    decoder.MessageEnd();
    word64 size = decoder.MaxRetrievable();
    char *decodedKey = new char[size];
    decoder.Get((byte *)decodedKey, size);
    // Generate Cipher, Key, and CBC
    byte key[ AES::MAX_KEYLENGTH ], iv[ AES::BLOCKSIZE ];
    StringSource( reinterpret_cast<const char *>(decodedKey), true,
                  new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH)) );
    memset( iv, 0x00, AES::BLOCKSIZE );
    CBC_Mode<AES>::Encryption Encryptor( key, sizeof(key), iv );
    StringSource( plain, true, new StreamTransformationFilter( Encryptor,
                  new HexEncoder(new StringSink( ciphertext )) ) );
    return QString::fromStdString(ciphertext);
}

QString AesUtils::decrypt(QString message, QString aesKey)
{
    string plain;
    string encrypted = message.toStdString();

    // Hex decode symmetric key:
    HexDecoder decoder;
    string stdAesKey = aesKey.toStdString();
    decoder.Put( (byte *)stdAesKey.data(), aesKey.size() );
    decoder.MessageEnd();
    word64 size = decoder.MaxRetrievable();
    char *decodedKey = new char[size];
    decoder.Get((byte *)decodedKey, size);
    // Generate Cipher, Key, and CBC
    byte key[ AES::MAX_KEYLENGTH ], iv[ AES::BLOCKSIZE ];
    StringSource( reinterpret_cast<const char *>(decodedKey), true,
                  new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH)) );
    memset( iv, 0x00, AES::BLOCKSIZE );
    try {
        CBC_Mode<AES>::Decryption Decryptor
        ( key, sizeof(key), iv );
        StringSource( encrypted, true,
                      new HexDecoder(new StreamTransformationFilter( Decryptor,
                                     new StringSink( plain )) ) );
    }
    catch (Exception &e) { // ...
        qDebug() << "Exception while decrypting " << e.GetWhat().data();
    }
    catch (...) { // ...
    }
        qDebug() << "decrypt" << plain.data() << " " << AES::BLOCKSIZE;
    return QString::fromStdString(plain);
}

Проблема в том, что я случайно получаю:

StreamTransformationFilter: invalid PKCS #7 block padding found

При расшифровке контента. Шифрование должно полностью поддерживать QString, поскольку он может содержать некоторые данные Unicode. Но это не работает даже с базовой строкой, которая содержит только [Az][az][0-9]

aesKey размер 256.

После некоторых ответов о переполнении стека кто-то предложил использовать HexDecoder / HexEncoder, но это не решает проблему в моем случае.

1 ответ

Первая проблема с моим кодом заключалась в том, что я передавал обычную строку в aesKey QString.

Поэтому вместо "1231fsdf$5r4" вам нужно указать ключ в шестнадцатеричном формате: [0-9][AF]

Тогда проблема была здесь:

char *decodedKey = new char[size];
decoder.Get((byte *)decodedKey, size);

Я предполагаю, что строка была полна 64 байта, и в конце не было места для NULL. Проблема исчезла после того, как я изменился на:

char *decodedKey = new char[size+2];

Теперь код работает нормально. Надеюсь, что это поможет кому-то в будущем.

Другие вопросы по тегам