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]