On Fri, Mar 27, 2009, Charles wrote: > 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; > > > 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 ""; > } > > }
Well it looks like one problem is the key. The default key size is 128 bits for EVP_bf_cbc() and "Test Key" is 64 bits or 72 bits if you include the final null. The rest is whatever garbage is after that buffer which may be consistent on back to back runs... So I'd suggest supplying 128 bits (16 characters) instead for the key. Steve. -- Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage OpenSSL project core developer and freelance consultant. Homepage: http://www.drh-consultancy.demon.co.uk ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org