The problem is using strcpy to copy the ciphertext. The ciphertext may
contain 0's in the middle, and strcpy will stop copying when it encounters
the 0 byte.
On Thu, Oct 21, 2004 at 05:05:19PM -0700, Tyler Gaede wrote:
> I'm looking to setup a simple password based encryption setup where
> someone can "password protect" a file for a program I'm writing. Only
> part of the file will be encrypted, and for ease of use I've been using
> strings rather than files for my sinks. I have succesfully compiled and
> integrated crypto++ into my program, but it is coughing up an error when
> I decode. I'm writing a basic CEncryption class that only has two
> methods: Encrypt & Decrypt (the code is below). If I encode a string,
> and then immediately try to decode it, I get an error. I am also using
> the Base64Encoder/Decoder, but I have taken it out for this example (and
> I have taken it out for testing as well).
>
> CEncryption::CEncryption()
> {
> m_nKeySize = AES::DEFAULT_KEYLENGTH; // 128
> }
>
> CEncryption::~CEncryption()
> {
> }
>
> void Transform(StreamTransformation& st, string& input, string& output)
> {
> StringSource(input, true, new StreamTransformationFilter(st, new
> StringSink(output)));
> }
>
> void GenerateKeyIV(SimpleKeyingInterface& ski, string& sPassphrase, int
> nKeySize)
> {
> int nSize = nKeySize + AES::BLOCKSIZE;
> SecByteBlock sbbKeyIV(nSize);
> PKCS12_PBKDF<SHA> pbkdf;
> nSize = ::strlen(sPassphrase.c_str());
> pbkdf.DeriveKey(sbbKeyIV.begin(), sbbKeyIV.size(), 0, (const
> byte*)sPassphrase.c_str(), nSize,
> (const byte*)sPassphrase.c_str(), nSize, 100, 0);
> ski.SetKeyWithIV(sbbKeyIV, nKeySize, sbbKeyIV + nKeySize);
> }
>
>
> void CEncryption::Encrypt(CString& password, CString& plainText,
> CString& cypherText)
> {
> try
> {
> string sInput = (LPCTSTR) plainText;
> string sOutput;
>
> string sPassphrase = (LPCTSTR) password;
>
> // just in case, reserve twice as much space
> sOutput.reserve( sInput.size() * 2 );
>
> CBC_Mode<AES>::Encryption encoder;
> GenerateKeyIV(encoder, sPassphrase, m_nKeySize);
> Transform(encoder, sInput, sOutput);
>
> strcpy(cypherText.GetBufferSetLength( sOutput.size() ),
> sOutput.c_str());
> }
> catch
> ...
> }
>
> void CEncryption::Decrypt(CString& password, CString& plainText,
> CString& cypherText)
> {
> try
> {
> string sInput;
> string sOutput;
> string sPassphrase = (LPCTSTR) password;
>
> // for some reason, a normal assignment like
> // sInput = (LPCTSTR) cypherText;
> // doesn't seem to copy the whole string. Or at least it reports
> the size
> // as different. If I do this append thing, then the size reports
> correctly.
>
> sInput.append( (LPCTSTR) cypherText, cypherText.GetLength() );
>
> sOutput.reserve( sInput.size() );
>
> CBC_Mode<AES>::Decryption decoder;
> GenerateKeyIV(decoder, sPassphrase, m_nKeySize);
> Transform(decoder, sInput, sOutput); // <-- Exception thrown here
>
> plainText = sOutput.c_str();
> }
> catch
> ...
> }
>
>
> The calls causing the error look like:
>
> crypto.Encrypt( m_sPassphrase, m_sPlain, m_sCypher );
> // m_sCypher now has the encrypted data in it.
> crypto.Decrypt( m_sPassphrase, m_sPlain2, m_sCypher );
>
> The exact error message is:
>
> CryptoPP::Exception caught: StreamTransformationFilter: invalid PKCS #7
> block padding found
>
> Version of Crypto++: 5.2.1
> Environment: Visual Studio 6.0 SP5 with Processor pack
>
> Any help would be greatly appreciated! Thanks in advance.
>
> Tyler
> [EMAIL PROTECTED]