Home > Net >  crypto Sending IV to another Function but i get an error: StreamTransformationFilter: invalid PKCS
crypto Sending IV to another Function but i get an error: StreamTransformationFilter: invalid PKCS

Time:11-22

Test Program to Encrypt using crypto , then it sends the iv and message as IV::EncryptedMessage.

I am able to encrypt but get a padding error #7 when decrypting, I've searched for hours but can't find anyway to pass a std::string IV to crypto .

I believe my error is in the decc function, where I use hexdecode?

string encc(string plain) {
    using namespace CryptoPP;

    AutoSeededRandomPool prng;


    SecByteBlock iv(AES::BLOCKSIZE);
    std::string sKey = "UltraSecretKeyPhrase";
    SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
    prng.GenerateBlock(iv, iv.size());
    std::string cipher, recovered;

    try
    {
        CBC_Mode< AES >::Encryption e;
        e.SetKeyWithIV(key, key.size(), iv);

        StringSource s(plain, true,
            new StreamTransformationFilter(e,
                new StringSink(cipher)
            ) 
        ); 
    }
    catch (const Exception& e)
    {
        exit(1);
    }

    string ciphertxt, ivString;

    HexEncoder encoder(new FileSink(std::cout));
    encoder.Detach(new StringSink(ivString));
    encoder.Put(iv, iv.size());
    encoder.MessageEnd();

    encoder.Detach(new StringSink(ciphertxt));
    encoder.Put((const byte*)&cipher[0], cipher.size());
    encoder.MessageEnd();

    string toSend = ivString   "::"   ciphertxt;
    return toSend;
}

string decc(string toDec) {
    using namespace CryptoPP;

    std::string sKey = "UltraSecretKeyPhrase";
    SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
    
    
    std::string recovered;
    string str1 = "::";

   
    size_t found = toDec.find(str1);
    if (found != string::npos) {

        std::string sIv = toDec.substr(0, found);
        std::string encMessage = toDec.substr(found   2, toDec.length());
        
        cout << endl << "IV: " << sIv << endl << "Encoded Msg: " << encMessage << endl;
        
        string iv;
        HexDecoder decoder;

        decoder.Attach(new StringSink(iv));
        decoder.Put((byte*)sIv.data(), sIv.size());
        decoder.MessageEnd();
        try
        {
            CBC_Mode< AES >::Decryption d;
            d.SetKeyWithIV(key.data(), key.size(), (byte *)iv.data(), AES::BLOCKSIZE);

            StringSource s(encMessage, true,
                new StreamTransformationFilter(d,
                    new StringSink(recovered)
                )
            );
            return recovered;
        }
        catch (const Exception& e)
        {
            std::cerr << e.what() << std::endl;
            exit(1);
        }
    }
    else return NULL;
}

int main(){
    string hh = encc("this is encoded");
    cout << hh << endl;
    string gg = decc(hh);
    cout << gg << endl;
    return 0;
}

Just can't seem to use the right words for google :)

CodePudding user response:

You have a decoding bug, instead of toDec.substr(found 2, toDec.length()) you should write toDec.substr(found 2, toDec.length() - (found 2)), because .substr() accepts number of symbols, not the end-position.

Maybe there are other bugs, but this definitely will break decoding process due to having garbarge inside encrypted message.

You may also just use toDec.substr(found 2), i.e. don't specify the count, if second param is not specified then substring is taken till the very end of string.

CodePudding user response:

I Decoded the hex of the IV but never the actual encrypted message. Of course I seen it after I posted smh...

This is a functional example of crypto encode and decode functions for anyone looking for it.


string encc(string plain) {
    using namespace CryptoPP;

    AutoSeededRandomPool prng;


    SecByteBlock iv(AES::BLOCKSIZE);
    std::string sKey = "UltraSecretKeyPhrase";
    SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
    prng.GenerateBlock(iv, iv.size());
    std::string cipher, recovered;

    try
    {
        CBC_Mode< AES >::Encryption e;
        e.SetKeyWithIV(key, key.size(), iv);

        StringSource s(plain, true,
            new StreamTransformationFilter(e,
                new StringSink(cipher)
            ) 
        ); 
    }
    catch (const Exception& e)
    {
        exit(1);
    }

    string ciphertxt, ivString;

    HexEncoder encoder(new FileSink(std::cout));
    encoder.Detach(new StringSink(ivString));
    encoder.Put(iv, iv.size());
    encoder.MessageEnd();

    encoder.Detach(new StringSink(ciphertxt));
    encoder.Put((const byte*)&cipher[0], cipher.size());
    encoder.MessageEnd();

    string toSend = ivString   "::"   ciphertxt;
    return toSend;
}

string decc(string toDec) {
    using namespace CryptoPP;

    std::string sKey = "UltraSecretKeyPhrase";
    SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
    
    
    std::string recovered;
    string str1 = "::";

   
    size_t found = toDec.find(str1);
    if (found != string::npos) {

        std::string sIv = toDec.substr(0, found);
        std::string encMessageHex = toDec.substr(found   2);
        
        cout << endl << "IV: " << sIv << endl << "Encoded Msg: " << encMessageHex << endl;
        
        string iv, encMessage;
        HexDecoder decoder, msgDecoder;

        decoder.Attach(new StringSink(iv));
        decoder.Put((byte*)sIv.data(), sIv.size());
        decoder.MessageEnd();
        // Forgot to decode encrypted message hex. added here
        decoder.Attach(new StringSink(encMessage));
        decoder.Put((byte*)encMessageHex.data(), encMessageHex.size());
        decoder.MessageEnd();
        try
        {
            CBC_Mode< AES >::Decryption d;
            d.SetKeyWithIV(key.data(), key.size(), (byte *)iv.data(), AES::BLOCKSIZE);

            StringSource s(encMessage, true,
                new StreamTransformationFilter(d,
                    new StringSink(recovered)
                )
            );
            return recovered;
        }
        catch (const Exception& e)
        {
            std::cerr << e.what() << std::endl;
            exit(1);
        }
    }
    else return NULL;
}

int main(){
    string hh = encc("this is encoded");
    cout << hh << endl;
    string gg = decc(hh);
    cout << gg << endl;
    return 0;
}
  • Related