Skip to Content
Personal Insights
Author's profile photo Vimal Sharma

Encryption logic for Payment files.

This blog is primarily written to help if you are looking for encryption logic in SAP.

There are 2 ways of enrcyption:

i) PGP – This would need PGP package installed in SAP(This is not covered in this blog)

ii) AES – Open source and can be done by executing commands at server level.

This blog is trying to address payment file scenerio(F110). The payment files generated should be encrypted and should have been decrypted by CPI or third party(as per the scenerio).

There can be multiple scenerio’s e.g. If we are doing AES from SAP and third party does not accept AES then CPI has to decrypt and encrypt again in PGP and send it to third party.

In any case, we have to ensure that the key which we are using should be accessible to third parties and they are able to decrypt the file.

Screenshot%20of%20end%20to%20functionality

Screenshot of end to functionality

 

  • Generate AES key and IV key :
  1. We can do this by writing a small test program in SE38 as shown below:
  2. In lt_result, you will get the Keys and IV keys. You can loop on it and print.
  3. Please don’t use CL_SEC_SXML_WRITER class to generate keys as it will not be accessible to third parties rather generate it with below commands at server level.
DATA: lt_result  TYPE TABLE OF char1024
      .
DATA(lv_str) = 'openssl enc -aes-256-cbc -k secret -P -md sha1' .

CALL 'SYSTEM' ID 'COMMAND' FIELD lv_str
              ID 'TAB'     FIELD lt_result[]
  • Create a table to save both Key and IV key(Saving a key is not recommended if you have a better approach , please follow.) .

 

  • PROG_NAME as primary key is kept to ensure if we have a scenerio where multiple programs needs multiple keys. So you can put your program name here and relevant keys.

Table%20structure

Table structure

  • Create a custom FM by copying standard test FM(FI_PAYMEDIUM_SAMPLE_41) provided by SAP. This will bring standard parameters and then copy paste below logic.

 

  • The logic is explained in code but at a high level this logic is trying to execute commands at server level to generate encrypted file(.aes) and remove the existing generated file and place the encrypted one in AL11 path.

 

  • This logic can be used to encrypt any other file  as well and not specifically payment files with some changes in logic.

 

  • Below are the text symbols which have commands:

001 chmod 777
002 openssl enc -e -aes-256-cbc -a -in
004 .aes

  • The only error you should get in below code is of custom table if naming convention is not same or fields are different.
  DATA: lv_fieldname      TYPE regut-fsnam      VALUE '(SAPLFPAYM10)GC_DME_FNAME',
        lv_flag_out       TYPE regut-fsnam      VALUE '(SAPFPAYM)PAR_XFIL',
        lv_path_org       TYPE regut-fsnam,
        lv_path_encrypted TYPE regut-fsnam,
        lv_cmd            TYPE char1024,
        lt_result2        TYPE TABLE OF char1024,
        gc_cr(1)          TYPE c,          "Carriage return code
        gc_lf(1)          TYPE c,          "Line feed code
        gc_eof(1)         TYPE c,          "End of line code..
        i_no_end_of_line  VALUE 'X',
        lv_key            TYPE zaes_key,
        lv_iv             TYPE zaes_iv,
        lv_keystr(200)    TYPE c,
        ls_string         TYPE string.
  FIELD-SYMBOLS: <fs_fieldname> TYPE any,
                 <fs_flag_out>  TYPE any.

  ASSIGN (lv_flag_out) TO <fs_flag_out>.

  IF  <fs_flag_out> EQ abap_true.

*Assign Standard file Name to Field Symbol
    ASSIGN (lv_fieldname) TO <fs_fieldname>.
    IF sy-subrc = 0.
      lv_path_org = <fs_fieldname> .
      CONCATENATE lv_path_org
                  TEXT-004
      INTO lv_path_encrypted.
    ENDIF.


    CLEAR ls_string.
*Append structure data to the existing file
*    OPEN DATASET lv_path_org FOR APPENDING IN LEGACY BINARY MODE.
*    IF sy-subrc = 0.
    CALL FUNCTION 'FI_DME_CHARACTERS'
      IMPORTING
        e_cr  = gc_cr
        e_lf  = gc_lf
        e_eof = gc_eof.
    LOOP AT t_file_output INTO DATA(ls_lines).
      IF ls_lines-length > 0.
        CLEAR ls_string.
        CONCATENATE ls_string ls_lines-line(ls_lines-length) INTO ls_string
                    RESPECTING BLANKS.
        IF i_no_end_of_line IS INITIAL.
          TRANSFER ls_string TO lv_path_org.
        ELSE.
          TRANSFER ls_string TO lv_path_org NO END OF LINE.
        ENDIF.
        IF sy-subrc NE 0.
          MESSAGE a229(bfibl02).
        ENDIF.
      ENDIF.
      IF NOT ls_lines-x_cr IS INITIAL.
        IF i_no_end_of_line IS INITIAL.
          TRANSFER gc_cr TO lv_path_org.
        ELSE.
          TRANSFER gc_cr TO lv_path_org NO END OF LINE.
        ENDIF.
        IF sy-subrc NE 0.
          MESSAGE a229(bfibl02).
        ENDIF.
      ENDIF.
      IF NOT ls_lines-x_lf IS INITIAL.
        IF i_no_end_of_line IS INITIAL.
          TRANSFER gc_lf TO lv_path_org.
        ELSE.
          TRANSFER gc_lf TO lv_path_org NO END OF LINE.
        ENDIF.
        IF sy-subrc NE 0.
          MESSAGE a229(bfibl02).
        ENDIF.
      ENDIF.
      IF NOT ls_lines-x_eof IS INITIAL.
        IF i_no_end_of_line IS INITIAL.
          TRANSFER gc_eof TO lv_path_org.
        ELSE.
          TRANSFER gc_eof TO lv_path_org NO END OF LINE.
        ENDIF.
        IF sy-subrc NE 0.
          MESSAGE a229(bfibl02).
        ENDIF.
      ENDIF.
*        ENdif
      CLEAR ls_lines.
    ENDLOOP.
*    ENDIF.

    CLOSE DATASET lv_path_org.

* Give 777 permission to the original file
    CONCATENATE TEXT-001
                lv_path_org
                INTO   lv_cmd SEPARATED BY space.

*  Command is executed
    CALL 'SYSTEM' ID 'COMMAND' FIELD lv_cmd
                  ID 'TAB'     FIELD lt_result2[].

    CLEAR: lv_cmd, lt_result2.
* Fetch key and IV from your custom table
    SELECT SINGLE aes_key iv_key INTO (lv_key,lv_iv ) FROM <yourzkeystable>
                                                        WHERE prog_name = 'ZXXX_PAYMEDIUM_41'
      .
    IF sy-subrc <> 0.
* Implement suitable error handling here
    ELSE.
      CONCATENATE '-K' lv_key
         '-iv' lv_iv
         INTO lv_keystr SEPARATED BY space.

* Aes 256 encryption
      CONCATENATE  TEXT-002
                   lv_path_org
                   '-out'
                   lv_path_encrypted
                   lv_keystr
                   INTO   lv_cmd SEPARATED BY space.

*   Command is executed
      CALL 'SYSTEM' ID 'COMMAND' FIELD lv_cmd
                    ID 'TAB'     FIELD lt_result2[].

* 777 Permission given to the encrypted file
      CLEAR: lv_cmd, lt_result2.

      CONCATENATE TEXT-001
                  lv_path_encrypted
                  INTO   lv_cmd SEPARATED BY space.

*   Command is executed
      CALL 'SYSTEM' ID 'COMMAND' FIELD lv_cmd
                    ID 'TAB'     FIELD lt_result2[].

    ENDIF.
    CLEAR:  t_file_output.
    REFRESH: t_file_output.
    FREE: t_file_output.

* Delete the Original file
    DELETE DATASET lv_path_org.
  ENDIF.

 

  • Go to transaction OBPM3-> Select Payment medium->Event Modules and put your custom FM in event 41  as shown below:

OBPM3

OBPM3

 

  • Now, Generate the payment files and in AL11 you will find file generated with .aes extension.
  • Also if you would like to debug the custom FM , you need to put the infinite loop and then start debugger from SM50.

 

Please let me know if any questions and doubt in above blog and we can correct it accordingly.

 

Thanks,

Vimal

 

 

Assigned Tags

      2 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Christophe Breton
      Christophe Breton

      Hi Vimal!

      Interesting post.

      But can you precise us what contains TEXT-001 and TEXT-002? It seems like they contain the command but which one?

      Thanks for the post,

      Christophe.

      Author's profile photo Vimal Sharma
      Vimal Sharma
      Blog Post Author

      Thanks for highlighting the gap.

      Updated the blog(above the FM code).