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]

Reply via email to