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.
- Generate AES key and IV key :
- We can do this by writing a small test program in SE38 as shown below:
- In lt_result, you will get the Keys and IV keys. You can loop on it and print.
- 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.
- 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
- 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:
- 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.
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,
Thanks for highlighting the gap.
Updated the blog(above the FM code).