I have a function that writes encryption of msg to filename using key
and iv.  I have another function that reads filename and decrypts msg
using key and iv.

If I run my encrypt function to create the encrypted file, and then
try and decrypt later with my decrypt function, I get this:

error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad
decrypt:evp_enc.c:461:

If, however, I run my encrypt and decrypt functions back to back, the
decryption works.  I think it's a block length or padding checking
problem, but can't figure out why it works sometimes.

i.e. this works:

        bf_encrypt( "test.bf", "Test msg", "Test key","12345678" );
        cout << bf_decrypt( "test.bf", "Test key","12345678" ) << endl;

And this doesn't:

//      bf_encrypt( "test.bf", "Test msg", "Test key","12345678" );
        cout << bf_decrypt( "test.bf", "Test key","12345678" ) << endl;

Charles



int bf_encrypt( string filename, string msg, string key, string iv ) {
        unsigned char outbuf[1024];
        int outlen, tmplen;
        
        EVP_CIPHER_CTX ctx;
        EVP_CIPHER_CTX_init( &ctx );
        EVP_EncryptInit_ex( &ctx, EVP_bf_cbc(), NULL, (const unsigned
char*)key.c_str(), (const unsigned char*)iv.c_str() );

        if( !EVP_EncryptUpdate( &ctx, outbuf, &outlen, (const unsigned
char*)msg.c_str(), msg.length() ) ) {
                /* Error */
                return 0;
        }

        if( !EVP_EncryptFinal_ex(&ctx, outbuf + outlen, &tmplen) ) {
                /* Error */
                return 0;
        }
        outlen += tmplen;
        EVP_CIPHER_CTX_cleanup(&ctx);

        ofstream out( filename.c_str(), ios::out | ios::binary );
        if( !out ) {
                cout << "Cannot open file.\n";
                return 0;
        }
        else {
                out.write((char *) &outbuf, outlen );
                out.close();
        }

        return 1;
}

std::string bf_decrypt( std::string filename, std::string key,
std::string iv ) {
        
        unsigned char outbuf[1024];
        int outlen, tmplen;
        
        ifstream file ( filename.c_str(), ios::in|ios::binary|ios::ate );

        if ( file.is_open() ) {
                ifstream::pos_type size;
                char * memblock;
                size = file.tellg();
                memblock = new char [size];
                file.seekg ( 0, ios::beg );
                file.read ( memblock, size );
                file.close();

                EVP_CIPHER_CTX ctx;
                
                EVP_CIPHER_CTX_init( &ctx );
                EVP_DecryptInit_ex( &ctx, EVP_bf_cbc(), NULL, (const unsigned
char*)key.c_str(), (const unsigned char*)iv.c_str() );
        
                if( !EVP_DecryptUpdate( &ctx, outbuf, &outlen, (const unsigned
char*)memblock, size ) ) {
                        cerr << "Error in EVP_DecryptUpdate" << endl;
                        return 0;
                }
                if( !EVP_DecryptFinal_ex( &ctx, outbuf + outlen, &tmplen ) ) {
                        cerr << "Error in EVP_DecryptFinal_ex:" << endl;
                        ERR_load_crypto_strings();
                        BIO * bo = BIO_new_fp( stdout, BIO_NOCLOSE );
                        ERR_print_errors( bo );
                        exit( 2 );
                }
                outlen += tmplen;
                EVP_CIPHER_CTX_cleanup( &ctx );
                delete[] memblock;
                std::string result ( reinterpret_cast<const char*>(outbuf), 
outlen );
                return result;
        }
        else {
                cerr << "Unable to open file";
                return "";
        }
        
}
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to