I posted this before but still haven't solved it:

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.  (Source below)

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