Using PGP encryption in ABAP program

 

1. Introduction

There many use cases where one wants to have the data encrypted before it is written to a file or send to an external application or integration platform. This blog describes one solution by using the Advantco PGP Webservice to encrypt/decrypt data in SAP ECC or SAP S/4HANA.

2.Architecture

The Advantco PGP Webservice (PGP WS) is an application that runs on any SAP JAVA Netweaver. The PGP WS exposes different SOAP services that handle the data encryption/decryption using PGP.

Using PGP encryption in ABAP program

3.Advantco PGP Webservice components

PGP Keymanager manages the PGP keys that are used by the PGP WS. This tool can generate new private key pairs, export public key for partners or import partner’s public key.

Using PGP encryption in ABAP program

PGP Webservices is the core of the solution, it provides the SOAP services to enable encryption/decryption and signing/verification of signatures.

Using PGP encryption in ABAP program

4. High level configuration and implementation steps.

Step 1: Goto Transaction Code [SE80] and create the webservice through Enterprise service option as below.

Using PGP encryption in ABAP program

Choose the Service Consumer->WSDL->URL option and pass the URL ( https://netweaver_host:port/AdvantcoOpenPGPSendingService/OpenPGPSendingService?wsdl&mode=ws_policy )
of Webservice OpenPGPSendingService
Save the service in Package->transport request and give the prefix to generate the Service Consumer as like below.

Using PGP encryption in ABAP program

Step 2: Go to Transaction code SOAMANAGER and choose the option “Web Service Configuration”
Select the Consumer service from search option by name and click on the service.
It will open the below screen to define the Logical Port.
Choose the WSDL based configuration option for creation of Port.

Using PGP encryption in ABAP program

Define Logical port will followed with wizard( step by step ) option. Pass the values and create the Port for SAP Server/Client in which Service Consumer has been created and activated. Save the Port as Logical Port Name ‘PGPSENDERPORT’

Using PGP encryption in ABAP program

Once Port has been created for specific Service Consumer-> WebService-> URL Check the Webservice thorogh “Ping Web Service” Button.

Step 3: When Service Consumer has been activated; System generate the Class and methods to call the webservice through SAP server by passing the Key, PhraseKey and Logicalport name. Data can be sent through encrypt and encrypt_text methods.

As an example of sending the vendor Invoice data, followed the below steps. The ABAP code below is just for sample purpose, it should be handle accordingly.
a) For MIGO transaction code -> Implemented the BADI INVOICE_UPDATE through transaction code SE18 -> Created the enhancement and BADI implementation class (ZCL_IM_PGP_SEND_INV_DETAIL) and implemented the methods of class.
b) Written the logic to the method -> IF_EX_INVOICE_UPDATE~CHANGE_BEFORE_UPDATE
c) Created new Function module (ZPGP_SEND_VENDOR_INV_DETAIL) to populate the data in local structure/table which will be passed in the encrypt_text method of class (ZPGPCO_OPEN_PGPSENDING_SERVICE) .
d) Once Parameter table( ZPGP_PARAM_VALUE) has been created to save the Key, passPharas and LogicalPort name for specific user.

Using PGP encryption in ABAP program

Decrypted the Key, Passphras and Lock Object values from ZPGP_PARAM_VALUE table and pass to method (encrypt_text) exporting parameter Input_text.

Once data has been sent to external webservice; It return the value in Binary mode(base64).

e) Convert the base64 data from im_output_text-encrypt_text_response-return.
Pass the value im_output_text-encrypt_text_response-return to XSTRING local available to LV_XSTR.
Converted the XSTRING to String by using the FM ‘SCMS_BASE64_ENCODE_STR’ and saved the data on application server file by using the Open dataset, Transfer and Close Dataset option.

function zpgp_send_vendor_inv_details.
    *"----------------------------------------------------------------------
    *"*"Local Interface:
    *"  IMPORTING
    *"     VALUE(ST_RBKP_NEW) TYPE  RBKP
    *"  EXPORTING
    *"     VALUE(ET_VEN_INV) TYPE  ZPGP_TT_VENDOR_INVOICE_DETAILS
    *"  TABLES
    *"      TT_MRMRSEG STRUCTURE  MRMRSEG OPTIONAL
    *"      TT_MRMRBCO STRUCTURE  MRMRBCO OPTIONAL
    *"      TT_MRMRBMA STRUCTURE  MRMRBMA OPTIONAL
    *"      TT_MRMRBTX STRUCTURE  MRMRBTX OPTIONAL
    *"      TT_MRMRBVS STRUCTURE  MRMRBVS OPTIONAL
    *"      TT_MRMRBWS STRUCTURE  MRMRBWS OPTIONAL
    *"----------------------------------------------------------------------
    
    *> This FM has been called from BADI INVOICE_UPDATE-> Implementation ZPGP_SEND_INV_DETAIL
    *> It sends the data to PGP through webservice when Transaction MIGO create the Vendor 
*> Invoice document. data: lo_senderpgp type ref to zpgpco_open_pgpsending_service, ex_input_text type zpgpencrypt_text_in, im_output_text type zpgpencrypt_text_out, lt_ven_inv type zpgp_tt_vendor_invoice_details, ls_ven_inv type zpgp_st_vendor_invoice_details, lv_str type string, lv_xstr type xstring, ls_str type string, lv_encoded_str type string, lv_decoded_str type string, lt_str type table of string. data : lv_tabname type dntab-tabname value 'ZPGP_ST_VENDOR_INVOICE_DETAILS', lv_wrbtr type char20, lv_menge type char20, ls_header type dntab, lt_header type standard table of dntab. data: lo_sfault type ref to cx_ai_system_fault, lo_jfault type ref to zpgpcx_encrypt_fault, lo_afault type ref to cx_ai_application_fault. select single * from zpgp_param_value into @data(ls_param_value)
where object_type = 'CLAS' and object_name = 'ZPGP_SEND_INV_DETAIL' and field_name = 'USER_INVOICE_KEY' and from_value = @sy-uname. check ls_param_value-text1 is not initial. *"---------------------------------------------------------------------- clear : lv_encoded_str, lv_decoded_str. lv_encoded_str = ls_param_value-text1. clear ls_param_value-text1. call method cl_http_utility=>if_http_utility~decode_base64 "Method for Decryption exporting encoded = lv_encoded_str receiving decoded = lv_decoded_str. call method cl_http_utility=>if_http_utility~decode_base64 "Method for Decryption exporting encoded = lv_decoded_str receiving decoded = lv_decoded_str. ls_param_value-text1 = lv_decoded_str. ex_input_text-parameters-encryption_key_id = ls_param_value-text1. " 'pgpkeyhere' . *"---------------------------------------------------------------------- clear : lv_encoded_str, lv_decoded_str. lv_encoded_str = ls_param_value-text2. clear ls_param_value-text2. call method cl_http_utility=>if_http_utility~decode_base64 "Method for Decryption exporting encoded = lv_encoded_str receiving decoded = lv_decoded_str. call method cl_http_utility=>if_http_utility~decode_base64 "Method for Decryption exporting encoded = lv_decoded_str receiving decoded = lv_decoded_str. ls_param_value-text2 = lv_decoded_str. ex_input_text-parameters-encryption_symmetric_passphras = ls_param_value-text2.
"'passwordhere' ."'0x594A9EB3'. *"---------------------------------------------------------------------- call function 'NAMETAB_GET' exporting tabname = lv_tabname tables nametab = lt_header. data(lv_no_of_columns) = lines( lt_header ). loop at lt_header into ls_header. if ls_str is initial. ls_str = ls_header-fieldtext. continue. endif. ls_str = | { ls_str } ; { ls_header-fieldtext } |. endloop. append ls_str to lt_str. read table tt_mrmrseg into data(ls_mrmrseg) index 1. move-corresponding ls_mrmrseg to ls_ven_inv. loop at tt_mrmrbco into data(ls_mrmrbco). move-corresponding ls_mrmrbco to ls_ven_inv. lv_wrbtr = ls_ven_inv-wrbtr. lv_menge = ls_ven_inv-menge. concatenate ls_ven_inv-belnr ls_ven_inv-gjahr ls_ven_inv-bukrs ls_ven_inv-blart ls_ven_inv-buzei lv_wrbtr ls_ven_inv-werks ls_ven_inv-saknr ls_ven_inv-kokrs ls_ven_inv-txjcd ls_ven_inv-ebeln ls_ven_inv-ebelp ls_ven_inv-matnr lv_menge ls_ven_inv-lfbnr into ls_str separated by ';'. append ls_str to lt_str. endloop. clear ls_str. concatenate lines of lt_str into lv_str separated by cl_abap_char_utilities=>cr_lf. ex_input_text-parameters-input_data = lv_str. try. clear : lv_encoded_str, lv_decoded_str. lv_encoded_str = ls_param_value-text3. clear ls_param_value-text3. call method cl_http_utility=>if_http_utility~decode_base64 "Method for Decryption exporting encoded = lv_encoded_str receiving decoded = lv_decoded_str. call method cl_http_utility=>if_http_utility~decode_base64 "Method for Decryption exporting encoded = lv_decoded_str receiving decoded = lv_decoded_str. ls_param_value-text3 = lv_decoded_str. create object lo_senderpgp exporting logical_port_name = ls_param_value-text3 .
"'PGPSENDERPORT'. catch cx_ai_system_fault . endtry. * call the ws try. try. call method lo_senderpgp->encrypt_text exporting input = ex_input_text importing output = im_output_text. catch cx_ai_system_fault into lo_sfault. exit. catch zpgpcx_encrypt_fault into lo_jfault. exit. catch cx_ai_application_fault into lo_afault. exit. endtry. select single * from zpgp_param_value into @data(ls_file_path)
where object_type = 'CLAS' and object_name = 'ZPGP_SEND_INV_DETAIL' and field_name = 'FILE_PATH' and from_value = @sy-uname. *>> write the binary xstring to a file open dataset dsn for output in text mode. check ls_file_path-text1 is not initial and im_output_text-encrypt_text_response-return
is not initial. clear : lv_xstr, lv_str. move im_output_text-encrypt_text_response-return to lv_xstr. call function 'SCMS_BASE64_ENCODE_STR' exporting input = lv_xstr importing output = lv_str. concatenate ls_file_path-text1 ls_mrmrseg-belnr '_' sy-datum sy-uzeit '.txt'
into ls_file_path-text1. condense ls_file_path-text1 no-gaps. open dataset ls_file_path-text1 in text mode for output encoding default. if sy-subrc ne 0. exit. endif. transfer lv_str to ls_file_path-text1. close dataset ls_file_path-text1. clear : lv_xstr, lv_str. endfunction.

f) Uploaded data will be available on application server [ AL11 ] as txt file like below

Using PGP encryption in ABAP program

5. Conclusion

Data can be encrypted before leaving the SAP back-end systems. The Advantco PGP Webservice provides a powerful solution that includes a PGP Keymanager and set of PGP services.

 


Please reach out to our sales team at sales@advantco.com if you have any questions.