Process a single AES-128-ECB block using C/C++ and openssl -


i want en- , decode single 16 bytes block of data using aes-128-ecb cipher. first did via openssl command line utility using ascii 16 characters string "a_key_simple_key" key , ascii 16 characters string "1234567890uvwxyz" message. command line utility printed hexadecimal string "142f 7d9e ad8c 0682 30e0 f165 a52f f789" ciphered message , decoded original message, see below:

$ echo -n "1234567890uvwxyz" | openssl aes-128-ecb -k $(echo -n "a_key_simple_key" | xxd -ps) -nopad | xxd 0000000: 142f 7d9e ad8c 0682 30e0 f165 a52f f789  ./}.....0..e./.. $ echo "142f 7d9e ad8c 0682 30e0 f165 a52f f789" | xxd -r -ps | openssl aes-128-ecb -d -k $(echo -n "a_key_simple_key" | xxd -ps) -nopad  1234567890uvwxyz 

now i've written short c++ program should same. doesn't work. there 2 issues:

  1. the output of encoding part 32 bytes long instead of 16 bytes (the first half of these 32 bytes ciphered text expected see)
  2. the decoding part failing in finalization step following openssl message:

error:06065064:digital envelope routines:evp_decryptfinal_ex:bad decrypt

i suspect both issues somehow connected padding, don't understand wrong , how fix it. here full output of program:

$ g++ -wall -g ssl-aes-128-ecb.c++ -lcrypto -lssl && ./a.out 2>&1 | less encoding: fail encoding: 1234567890uvwxyz --> ^t/}<9e><ad><8c>^f<82>0<e0><f1>e<a5>/<f7><89>^x<a0>p<u+dace>r<f8>a^r^a<8a><97>gf* error:06065064:digital envelope routines:evp_decryptfinal_ex:bad decrypt aborting in u_string decode(u_string, u_string) @ ssl-aes-128-ecb.c++:56 

and here c++ program (with line numbers):

01 #include <string> 02 #include <iostream> 03 #include <openssl/evp.h> 04 #include <openssl/err.h> 05 #include <openssl/ssl.h> 06 #define abort() (fprintf(stderr, "%s\naborting in %s @ %s:%d\n", err_error_string(err_get_error(), null), __pretty_function__, __file__, __line__), abort(), 0) 07 08 typedef std::basic_string<unsigned char> u_string; 09 static u_string encode(u_string key, u_string data); 10 static u_string decode(u_string key, u_string data); 11 12 // echo -n "1234567890uvwxyz" | openssl aes-128-ecb -k $(echo -n "a_key_simple_key" | xxd -ps) -nopad | xxd 13 // echo "142f 7d9e ad8c 0682 30e0 f165 a52f f789" | xxd -r -ps | openssl aes-128-ecb -d -k $(echo -n "a_key_simple_key" | xxd -ps) -nopad 14 15 int main() 16 { 17   ssl_load_error_strings(); 18 19   u_string key = (unsigned char *) "a_key_simple_key"; 20   u_string clear_text = (unsigned char *) "1234567890uvwxyz"; 21   u_string secret_txt = (unsigned char *) "\x14\x2f" "\x7d\x9e" "\xad\x8c" "\x06\x82" "\x30\xe0" "\xf1\x65" "\xa5\x2f" "\xf7\x89"; 22 23   std::cerr << "encoding: " << (encode(key, clear_text)==secret_txt ? "ok" : "fail") << std::endl; 24   std::cerr << "encoding: " << (char*)clear_text.c_str() << " --> " << (char*)encode(key, clear_text).c_str() << std::endl; 25   std::cerr << "decoding: " << (decode(key, secret_txt)==clear_text ? "ok" : "fail") << std::endl; 26   std::cerr << "decoding: " << (char*)secret_txt.c_str() << " --> " << (char*)decode(key, secret_txt).c_str() << std::endl; 27 28   return 0; 29 } 30 31 static u_string encode(u_string key, u_string data) 32 { 33   evp_cipher_ctx ctx; 34   evp_cipher_ctx_init(&ctx); 35   evp_cipher_ctx_set_padding(&ctx, false); 36   evp_encryptinit_ex (&ctx, evp_aes_128_ecb(), null, key.c_str(), null); 37   unsigned char buffer[1024], *pointer = buffer; 38   int outlen; 39   evp_encryptupdate (&ctx, pointer, &outlen, data.c_str(), data.length()) or abort(); 40   pointer += outlen; 41   evp_encryptfinal_ex(&ctx, pointer, &outlen) or abort(); 42   pointer += outlen; 43   return u_string(buffer, pointer-buffer); 44 } 45 46 static u_string decode(u_string key, u_string data) 47 { 48   evp_cipher_ctx ctx; 49   evp_cipher_ctx_init(&ctx); 50   evp_cipher_ctx_set_padding(&ctx, false); 51   evp_decryptinit_ex (&ctx, evp_aes_128_ecb(), null, key.c_str(), null); 52   unsigned char buffer[1024], *pointer = buffer; 53   int outlen; 54   evp_decryptupdate (&ctx, pointer, &outlen, data.c_str(), data.length()) or abort(); 55   pointer += outlen; 56   evp_decryptfinal_ex(&ctx, pointer, &outlen) or abort(); 57   pointer += outlen; 58   return u_string(buffer, pointer-buffer); 59 } 

ok, seems figured out what's wrong:

evp_cipher_ctx_set_padding() call must done after evp_decryptinit_ex() call

so solution exchange lines 50/51 , 35/36.


Comments

Popular posts from this blog

Change php variable from jquery value using ajax (same page) -

Pull out data related to my apps from Android Play Store and iOS App Store -

How can I fetch data from a web server in an android application? -