StreamTransformationFilter: invalid PKCS #7 block padding found (Crypto++)

I am trying to decrypt ciphertext provided by a user using a Qt QLineEdit.

If I encrypt the string and then decrypt it using the code below, everything works as expected.

crypto::aes_pbkdf2_decrypt(crypto::aes_pbkdf2_encrypt("ciphertxt", "keystr"), "keystr");

When the string is encrypted, it gets an output to a QtLineEdit. When I attempt to decrypt that ciphertext output, it throws StreamTransformationFilter: invalid PKCS #7 block padding found.

This doesn't make much sense to me since it works perfectly when I directly decrypt the output from the encryption function as shows above.

Here are the functions I am using for encryption/decryption:

Encrypt

std::string crypto::aes_pbkdf2_encrypt(std::string pPlainText, std::string pKey)
{ CryptoPP::AutoSeededRandomPool prng; CryptoPP::SecByteBlock iv (CryptoPP::AES::BLOCKSIZE); CryptoPP::SecByteBlock salt (CryptoPP::AES::DEFAULT_KEYLENGTH / 2); CryptoPP::SecByteBlock key (CryptoPP::AES::DEFAULT_KEYLENGTH); std::string cipher, output, cipher_str, iv_str, salt_str; prng.GenerateBlock(salt, salt.size()); prng.GenerateBlock(iv, iv.size()); key = pbkdf2_salt_hash(pKey, salt); try { CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encrypt; encrypt.SetKeyWithIV(key, key.size(), iv); CryptoPP::StringSource stringsource(pPlainText, true, new CryptoPP::StreamTransformationFilter(encrypt, new CryptoPP::StringSink(cipher) ) ); } catch (const CryptoPP::Exception& e) { std::cerr << e.what() << std::endl; return ""; } CryptoPP::HexEncoder encoder (new CryptoPP::FileSink(std::cout)); encoder.Detach(new CryptoPP::StringSink(salt_str)); encoder.Put(salt, salt.size()); encoder.MessageEnd(); encoder.Detach(new CryptoPP::StringSink(iv_str)); encoder.Put(iv, iv.size()); encoder.MessageEnd(); encoder.Detach(new CryptoPP::StringSink(cipher_str)); encoder.Put((const CryptoPP::byte*) &cipher[0], cipher.size()); encoder.MessageEnd(); output = iv_str + cipher_str + salt_str; std::cout << "Cipher: " << output << std::endl; return output;
}

Decrypt

std::string crypto::aes_pbkdf2_decrypt(std::string pCipherText, std::string pKey)
{ std::string iv_str = pCipherText.substr(0, 32); std::string salt_str = pCipherText.substr(pCipherText.size() - 16, pCipherText.size()); std::string cipher_str = pCipherText.substr(iv_str.size(), pCipherText.size() - (iv_str.size() + salt_str.size())); std::string iv, salt, cipher, output; CryptoPP::HexDecoder decoder(new CryptoPP::FileSink(std::cout)); decoder.Attach(new CryptoPP::StringSink(iv)); decoder.Put((CryptoPP::byte*) iv_str.data(), iv_str.size()); decoder.MessageEnd(); decoder.Attach(new CryptoPP::StringSink(salt)); decoder.Put((CryptoPP::byte*) salt_str.data(), salt_str.size()); decoder.MessageEnd(); decoder.Attach(new CryptoPP::StringSink(cipher)); decoder.Put((CryptoPP::byte*) cipher_str.data(), cipher_str.size()); decoder.MessageEnd(); try { CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption decryptor; CryptoPP::SecByteBlock salt_blk ((CryptoPP::byte*) salt.data(), salt.size()); CryptoPP::SecByteBlock iv_blk ((CryptoPP::byte*) iv.data(), iv.size()); CryptoPP::SecByteBlock key = pbkdf2_salt_hash(pKey, salt_blk); decryptor.SetKeyWithIV(key.data(), key.size(), iv_blk); CryptoPP::StringSource stringsource (cipher, true, new CryptoPP::StreamTransformationFilter(decryptor, new CryptoPP::StringSink(output) ) ); } catch (const CryptoPP::Exception& e) { std::cerr << e.what() << std::endl; return ""; } return output;
}

PBKDF2 Hashing

CryptoPP::SecByteBlock crypto::pbkdf2_salt_hash(std::string pPlainText, CryptoPP::SecByteBlock pSalt)
{ CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA256> pbkdf; CryptoPP::SecByteBlock output(CryptoPP::AES::DEFAULT_KEYLENGTH); CryptoPP::byte text_bytes[pPlainText.size()]; std::memcpy(text_bytes, pPlainText.data(), pPlainText.size()); size_t plaintext_length = strlen((const char*)text_bytes); size_t salt_length = pSalt.size(); pbkdf.DeriveKey(output, output.size(), 0, text_bytes, plaintext_length, pSalt, salt_length, 1024, 0.0f); return output;
}

What I have already tried:

I tried each padding type in CryptoPP::BlockPaddingSchemeDef::BlockPaddingScheme to CryptoPP::StringSink in the decryption function. Only creates odd 'OpenType' errors and strangely formatted outputs.

3 Related questions 1 Error in outputting to a file in C++ that I can't find 0 QCA QtCrypto in QT Problem 0 Encrypt QDataStream with AES Related questions 1 Error in outputting to a file in C++ that I can't find 0 QCA QtCrypto in QT Problem 0 Encrypt QDataStream with AES 1 AES decryption and 'invalid pkcs #7 block padding' 2 StreamTransformationFilter: invalid PKCS #7 block padding found in AES decryption 0 CryptographicException: Bad PKCS7 padding. Invalid length 137 0 StreamTransformationFilter: ciphertext length is not a multiple of block size? 2 Crypto++ extra block at the end of encrypted stream in AES-128 CBC mode 1 StreamTransformationFilter: invalid PKCS #7 block padding found using AES decryption 0 error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding openssl C++ Load 7 more related questions Show fewer related questions Reset to default

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like