AES decryption in ABAP

A few weeks ago I was challenged to decrypt a file in ABAP that was encrypted using the AES256 CBC protocol. Have you ever tried to decrypt a file? I succeeded, and this is how:

The file I received was encrypted with AES256 encryption. Never used that before, so I decided to use my best friend Google to search for information. I bumped into a very cool Git Repository which didn’t only contain the classes I needed to decrypt my file, it contains a lot more possibilities for encryption and decryption. You can find the repository here.

The picture below shows the encrypted data which is in the file we will be processing in this blog.

I started with the implementation of the classes from the Git Repository and wrote a simple program without error and message handling. It shows you how an AES256 encrypted file can be read and decrypted using some of the classes from Git. First step is to fetch the encrypted data from the server in xstring format. The method read_file( ) reads the file from the server and returns the result in xstring format.

  DATA(lo_decrypt)  = NEW zcl_proc_decrypt( ).

  lo_decrypt->set_generationnr( iv_gennr = '00001' ). " fixed value because this is just a test

  lv_x_data = lo_decrypt->read_file( EXPORTING iv_dir  = p_dir
                                               iv_file = |{ p_encr }| && 
                                                         |.| && 
                                                         |{ lo_decrypt->co_gen_prefix }| &&
                                                         |00001| ).

This is the result of the method read_file( ). As you can see this is still pretty unreadable.

In the example I use for this blog, the files are always encrypted with the same KEY and IV (initialization vector). To be able to use the KEY and IV in the rest of the process the data must be converted to an xstring datatype. The code below also shows that class ZCL_AES_UTILITY is used, which checks the validity of the KEY and IV. If one of those is not valid, then the decryption can not be done.

  lv_x_key = lo_decrypt->get_key( ).
  lv_x_iv  = lo_decrypt->get_iv( ).

  IF NOT zcl_aes_utility=>is_valid_key_xstring( lv_x_key ) = abap_true AND
         zcl_aes_utility=>is_valid_iv_xstring( i_initialization_vector = lv_x_iv ) = abap_true.
   " message no valid KEY and IV found
    EXIT.
  ENDIF.

Now the real fun starts, which is the decryption part. It’s important to know with which protocol the file was encrypted, because that’s the protocol you must use in the decryption process. As you can see my file was encrypted using ‘CBC’ (Cipher Block Chaining mode).

In the first step of the codeblock below, the file is encrypted and the method decrypt_xstring( ) returns the data in xstring format. To be able to use the data, which is now in xstring format, it has to be converted to a normal string. Method convert_xstring_to_string( ) takes care of this. In this method the functions SCMS_XSTRING_TO_BINARY followed by SCMS_BINARY_TO_STRING convert the data back to a normal string.

*-- decrypt payload
  zcl_aes_utility=>decrypt_xstring( EXPORTING i_key                   = lv_x_key
                                              i_data                  = lv_x_data
                                              i_initialization_vector = lv_x_iv
                                              i_padding_standard      = zcl_byte_padding_utility=>mc_padding_standard_pkcs_7
                                              i_encryption_mode       = 'CBC'
                                    IMPORTING e_data                  = lv_x_result ).

  DATA(lv_result) = lo_decrypt->convert_xstring_to_string( 
                                EXPORTING iv_x_result = lv_x_result ).

  DATA(lt_decrypted) = lo_decrypt->convert_string_to_table( iv_result = lv_result ).

  lo_decrypt->upload_to_appserver( EXPORTING it_datatab      = lt_decrypted " tab of strings
                                             iv_dir          = p_dir        " UNIX directory
                                             iv_filename     = p_decr       " UNIX filename
                                             iv_filename_enc = p_encr ).   

The output of the method convert_xstring_to_string( ) is already in a readable format, however, it’s still in string format where all data is presented on one line.

The method convert_string_to_table( ) splits the data into several lines using CL_ABAP_CHAR_UTILITIES=>NEWLINE to determine where the data should be split.

Last step is to place the decrypted the file on the server. The file now looks like this, a perfectly decrypted file!