The problem turned out to be in CryptStreamBuffer::GetNextChar() and
was fixed by replacing:
// If there are no more bytes currently available then pump the source
if (m_StreamTransformationFilter->MaxRetrievable() == 0) {
m_Source->Pump(1024);
}
With the following which ewnsure that the last few bytes are
processed:
// If there are no more bytes currently available from the filter then
// pump the source.
if (m_StreamTransformationFilter->MaxRetrievable() == 0) {
if (0 == m_Source->Pump(1024)) {
// This seems to be required to ensure the final bytes are
readable
// from the filter.
m_StreamTransformationFilter-
>ChannelMessageEnd(CryptoPP::DEFAULT_CHANNEL);
}
}
Tom
On Jun 16, 6:46 pm, Don <[email protected]> wrote:
> here is your answer.
> It has to do with the cipher that you picked.
>
> "ECB Mode is electronic codebook. ECB was originally specified by NIST
> in FIPS 81. The standard, issued in 1981, only offers confidentiality.
> Other modes, such as CCM and GCM, offer authenticated encryption which
> places an integrity assurance over the encrpyted data.
>
> <B>ECB mode does not use an IV, and the plain text must be padded to
> the block size of the cipher</B>. For additional information on this
> mode, see Block Cipher Modes of Operation. "
>
> On Jun 16, 12:05 pm, Don <[email protected]> wrote:
>
> > Hi
> > I compiled your code and your stopping on the last BLOCKSIZE boundary.
> > Bet your losing the remainder and only getting even BLOCKSIZE out put.
>
> > In other words your not losing 16 bytes your losing the last < 16
> > bytes.
>
> > don
>
> > I will see if I can find out why.
>
> > On Jun 11, 10:54 am, Tom <[email protected]> wrote:
>
> > > Hi,
>
> > > To answer my own previous question (http://groups.google.com/group/
> > > cryptopp-users/browse_thread/thread/721dbd6fa5992a57) I wrote the code
> > > given at the end of this post.
>
> > > However it appears that DecryptFile() is not attempting to decrypt the
> > > last 16 bytes (block size) of the encrypted file. Can anybody tell me
> > > what I am doing wrong?
>
> > > Yours truly,
>
> > > Tom
>
> > > --------------------------------------------------------------------------------
>
> > > // Runtime Includes
> > > #include <iostream>
>
> > > // Crypto++ Includes
> > > #include "aes.h"
> > > #include "modes.h" // xxx_Mode< >
> > > #include "filters.h" // StringSource and
> > > // StreamTransformation
> > > #include "files.h"
>
> > > using namespace std;
>
> > > class CryptStreamBuffer: public std::streambuf {
>
> > > public:
>
> > > CryptStreamBuffer(istream& encryptedInput,
> > > CryptoPP::StreamTransformation& c);
>
> > > CryptStreamBuffer(ostream& encryptedOutput,
> > > CryptoPP::StreamTransformation& c);
>
> > > protected:
> > > virtual int_type overflow(int_type ch = traits_type::eof());
>
> > > virtual int_type uflow();
>
> > > virtual int_type underflow();
>
> > > virtual int_type pbackfail(int_type ch);
>
> > > virtual int sync();
>
> > > private:
> > > int GetNextChar();
>
> > > int m_NextChar; // Buffered character
>
> > > CryptoPP::StreamTransformationFilter*
> > > m_StreamTransformationFilter;
>
> > > CryptoPP::FileSource* m_Source;
>
> > > CryptoPP::FileSink* m_Sink;
>
> > > }; // class CryptStreamBuffer
>
> > > CryptStreamBuffer::CryptStreamBuffer(istream& encryptedInput,
> > > CryptoPP::StreamTransformation& c) :
> > > m_NextChar(traits_type::eof()),
> > > m_StreamTransformationFilter(0),
> > > m_Source(0),
> > > m_Sink(0) {
>
> > > m_StreamTransformationFilter = new
> > > CryptoPP::StreamTransformationFilter(c);
> > > m_Source = new CryptoPP::FileSource(encryptedInput, false,
> > > m_StreamTransformationFilter);
>
> > > }
>
> > > CryptStreamBuffer::CryptStreamBuffer(ostream& encryptedOutput,
> > > CryptoPP::StreamTransformation& c) :
> > > m_NextChar(traits_type::eof()),
> > > m_StreamTransformationFilter(0),
> > > m_Source(0),
> > > m_Sink(0) {
>
> > > m_Sink = new CryptoPP::FileSink(encryptedOutput);
> > > m_StreamTransformationFilter = new
> > > CryptoPP::StreamTransformationFilter(c, m_Sink);
>
> > > }
>
> > > CryptStreamBuffer::int_type CryptStreamBuffer::overflow(int_type ch) {
>
> > > return m_StreamTransformationFilter->Put((byte)ch);
>
> > > }
>
> > > CryptStreamBuffer::int_type CryptStreamBuffer::uflow() {
>
> > > int_type result = GetNextChar();
>
> > > // Reset the buffered character
> > > m_NextChar = traits_type::eof();
>
> > > return result;
>
> > > }
>
> > > CryptStreamBuffer::int_type CryptStreamBuffer::underflow() {
>
> > > return GetNextChar();
>
> > > }
>
> > > CryptStreamBuffer::int_type CryptStreamBuffer::pbackfail(int_type ch)
> > > {
>
> > > return traits_type::eof();
>
> > > }
>
> > > int CryptStreamBuffer::sync() {
>
> > > if (m_Sink) {
> > > m_StreamTransformationFilter->MessageEnd();
> > > }
>
> > > }
>
> > > int CryptStreamBuffer::GetNextChar() {
>
> > > // If we have a buffered character do nothing
> > > if (m_NextChar != traits_type::eof()) {
> > > return m_NextChar;
> > > }
>
> > > // If there are no more bytes currently available then pump the
> > > source
> > > if (m_StreamTransformationFilter->MaxRetrievable() == 0) {
> > > m_Source->Pump(1024);
> > > }
>
> > > // Retrieve the next byte
> > > byte nextByte;
> > > size_t noBytes = m_StreamTransformationFilter->Get(nextByte);
> > > if (0 == noBytes) {
> > > return traits_type::eof();
> > > }
>
> > > // Buffer up the next character
> > > m_NextChar = nextByte;
>
> > > return m_NextChar;
>
> > > }
>
> > > void InitKey(byte key[]) {
>
> > > key[0] = -62;
> > > key[1] = 102;
> > > key[2] = 78;
> > > key[3] = 75;
> > > key[4] = -96;
> > > key[5] = 125;
> > > key[6] = 66;
> > > key[7] = 125;
> > > key[8] = -95;
> > > key[9] = -66;
> > > key[10] = 114;
> > > key[11] = 22;
> > > key[12] = 48;
> > > key[13] = 111;
> > > key[14] = -51;
> > > key[15] = 112;
>
> > > }
>
> > > void DecryptFile(const char* sourceFileName, const char* destFileName)
> > > {
>
> > > ifstream ifs(sourceFileName, ios::in | ios::binary);
> > > ofstream ofs(destFileName, ios::out | ios::binary);
>
> > > byte key[CryptoPP::AES::DEFAULT_KEYLENGTH];
> > > InitKey(key);
> > > CryptoPP::ECB_Mode<CryptoPP::AES>::Decryption decryptor(key,
> > > sizeof(key));
>
> > > if (ifs) {
> > > if (ofs) {
> > > CryptStreamBuffer cryptBuf(ifs, decryptor);
> > > std::istream decrypt(&cryptBuf);
>
> > > int c;
> > > while (EOF != (c = decrypt.get())) {
> > > ofs << (char)c;
> > > }
> > > ofs.flush();
> > > }
> > > else {
> > > std::cerr << "Failed to open file '" << destFileName <<
> > > "'." << endl;
> > > }
> > > }
> > > else {
> > > std::cerr << "Failed to open file '" << sourceFileName << "'."
> > > << endl;
> > > }
>
> > > }
>
> > > void EncryptFile(const char* sourceFileName, const char* destFileName)
> > > {
>
> > > ifstream ifs(sourceFileName, ios::in | ios::binary);
> > > ofstream ofs(destFileName, ios::out | ios::binary);
>
> > > byte key[CryptoPP::AES::DEFAULT_KEYLENGTH];
> > > InitKey(key);
>
> > > CryptoPP::ECB_Mode<CryptoPP::AES>::Encryption encryptor(key,
> > > sizeof(key));
>
> > > if (ifs) {
> > > if (ofs) {
> > > CryptStreamBuffer cryptBuf(ofs, encryptor);
> > > std::ostream encrypt(&cryptBuf);
>
> > > int c;
> > > while (EOF != (c = ifs.get())) {
> > > encrypt << (char)c;
> > > }
> > > encrypt.flush();
> > > }
> > > else {
> > > std::cerr << "Failed to open file '" << destFileName <<
> > > "'." << endl;
> > > }
> > > }
> > > else {
> > > std::cerr << "Failed to open file '" << sourceFileName << "'."
> > > << endl;
> > > }
>
> > > }
>
> > > int main(int argc, char* argv[])
> > > {
> > > EncryptFile(argv[1], "encrypted.out");
> > > DecryptFile("encrypted.out", "decrypted.out");
> > > return 0;
>
> > > }
>
> > > ---------------------------------------------------------------------------------
> > > Hide quoted text -
>
> > - Show quoted text -
--
You received this message because you are subscribed to the "Crypto++ Users"
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at
http://www.cryptopp.com.