Recently we had a requirement in our organization to implement encryption for all data transmission happening from SAP to external systems to have an additional layer of security. The requirement was to AES256 encrypt and Base64 Encode the information shared between the systems.The encryption/decryption was done with a common key which gets generated in SAP and shared through automated email from the system.
SAP Class/Function Modules used for the process:
- CL_SEC_SXML_WRITER is used to implement the logic for generation of AES key and encryption/decryption of information.
- SCMS_BASE64_<EN/DE>CODE_STR FM is being used for Base64 Encoding/Decoding the information.
High Level Process Flow
Following are the steps and sample code we have used for encryption/decryption.
Generate Encryption Key
We use following logic to generate Key for encryption which is stored in a table and then shared with external systems.
*Sample Code to generate Key: data: random type xstring, wa_bench_config type zhr_bench_config. call method cl_sec_sxml_writer=>generate_key exporting algorithm = cl_sec_sxml_writer=>co_aes256_algorithm receiving key = random. data(lr_conv_key) = cl_abap_conv_out_ce=>create( ). lr_conv_key->write( data = random ). e_key = lr_conv_key->get_buffer( ).
External System sends AES encrypted and Base64 encoded data and in SAP we used following logic to decrypt the text.
data: i_key_xstring type xstring, i_iv type xstring. i_iv = '00000000000000000000000000000000'. if i_text is not initial. call function 'SCMS_BASE64_DECODE_STR' exporting input = i_text * UNESCAPE = 'X' importing output = i_xstring * EXCEPTIONS * FAILED = 1 * OTHERS = 2 . if sy-subrc <> 0. * Implement suitable error handling here endif. endif. if i_xstring is not initial. * For CL_SEC_SXML_WRITER to work with external application we need to add 16 bit * extra padding before decryption concatenate i_iv(16) i_xstring into i_xstring in byte mode. try. cl_sec_sxml_writer=>decrypt( exporting ciphertext = i_xstring key = i_key_xstring algorithm = cl_sec_sxml_writer=>co_aes256_algorithm_pem importing plaintext = data(lv_message_decrypted) ). " convert xstring to string for output cl_abap_conv_in_ce=>create( input = lv_message_decrypted )->read( importing data = e_text_dec ). catch cx_sec_sxml_encrypt_error into data(oref). . endtry. endif.
SAP processes the information and sends encrypted response back using following logic:
data(lr_conv_sec) = cl_abap_conv_out_ce=>create( ). lr_conv_sec->write( data = i_text ). " encrypt using AES256 i_xstring = lr_conv_sec->get_buffer( ). i_iv = '00000000000000000000000000000000'. cl_sec_sxml_writer=>encrypt_iv( exporting plaintext = i_xstring key = i_key_xstring iv = i_iv algorithm = cl_sec_sxml_writer=>co_aes256_algorithm_pem importing ciphertext = data(lv_message) ). data: lr_conv type ref to cl_abap_conv_in_ce, lr_xstring type xstring, lr_string type string. *Before sending encrypted information to external system, remove the extra *16 bit padding from the xstring lr_xstring = lv_message+16. data: lt_data type tsfixml, l_len type i. call function 'SCMS_BASE64_ENCODE_STR' exporting input = lr_xstring importing output = e_text_enc. endif.
EXAMPLE: Text: Test AES@CBC#PKCS$5 Encrypted Text : B8Q1+w5vH9jG3V/ejYg5igeGNgfX6nvqUGrDnogyDdo= After Decryption : Test AES@CBC#PKCS$5
The blog post provides information on how to encrypt and decrypt information in SAP and how you can plan the integration with external systems. The sample code here works for AES256/CBC/PKCS5 Padding algorithm, but CL_SEC_SXML_WRITER class has other AES encryption algorithms as well.
Please note along with the encryption key, we also need to share the IV key which is 16bit hexadecimal string (‘0000000000000000’).
Hopefully this blog post will help in implementing similar requirements where we need to send encrypted information between multiple systems.