EDUCAÇÃO E TECNOLOGIA

AES Decryption in Fiori & Encryption in ABAP

Introduction

Recently we had a requirement in our organization to implement encryption for some data transmission from Fiori to SAP with oData.  The requirement was to AES256 encrypt the information shared between the systems.

SAP Class/Function Modules & JS Libs used for the process:

  • From crypto-js library AES.js file is used to implement the logic for generation of AES key and encryption of information.
  • CL_SEC_SXML_WRITER is used to decryption of information.
  • SCMS_STRING_TO_XSTRING is used to convert string to xstring
  • /ui2/cl_abap2json is used to convert xstring to string

Import JS Library to your Project

  • First download CryptoJS zip from https://code.google.com/archive/p/crypto-js/downloads. I used the version 3.1.2. 
  • Unzip it in your computer. In rollups file you will find aes.js, copy it to your Project/webapp folder.

Bild1

Bild1

  • Now we have to import aes.js Javascript Lib in our Main controller or the controller you want to use.
  • Add the following command to top of your controller “jQuery.sap.require(“yourUploadedAESFileDirection”)”

Bild2

Generate Encryption Key & Encryption (in FIori JS)

I used following logic to generate Key for encryption in JavaScript and sending to SAP via oData Service.

*IV: In cryptography, an initialization vector (IV) is an input to a cryptographic primitive being used to provide the initial state. The IV is typically required to be random. Randomization is crucial for some encryption schemes to achieve semantic security, a property whereby repeated usage of the scheme under the same key does not allow an attacker to infer relationships between (potentially similar) segments of the encrypted message.

Note: Use your own ramdom created IV. And the randomly generated Key length should be 32 characters.

Encryption:

// This is our Secret Message ChiperText
let data = "THIS IS MY SECRET KEY";
//initialization vector for additional secure
let iv = 'ThisIs33221321OurIV1ar234567';
//Your key length should be 32 characters, you should generate your own random key every time
let key = 'THISISOURKEY1234567WORKSTATION01'; // prepare key & iv for CryptoJS encryption
let fkey = CryptoJS.enc.Utf8.parse(key);
let fiv = CryptoJS.enc.Utf8.parse(iv); //Encyrption
//We access the library with calling "CryptoJS" //and it returns the encrypted value in "enc.ciphertext"
let enc = CryptoJS.AES.encrypt(data, fkey, { iv: fiv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7,
}); 

Sending to SAP:

let aFilters = [];
//Call your oData Service to send the encrypted text
//We used here just one Filter with name of "KEY"
//To send the text we change the format of "enc.ciphertext" as string
aFilters.push(new Filter("KEY", FilterOperator.EQ, enc.ciphertext.toString()));
this.getView().getModel().read("/CryptoSet", { filters: aFilters, success: function (oData, response) { //do something }.bind(this), error: function (oError) { //do something }.bind(this) });

You can use a function call instead of entity set. its up to you. If you want to follow my way you can get more information about oData services entitySet on following link.

https://blogs.sap.com/2021/05/19/a-step-by-step-process-to-post-odata-services-in-sap-sap-hana-system/

Decryption on Serverside (ABAP)

Here you can copy bellow code in your oData Service class “*_DPC_EXT” in your entitySet method.

Variable declaration

 "Encryption Parameters DATA: lt_binary TYPE STANDARD TABLE OF x255. DATA: i_xstring TYPE xstring, lx_plaintext TYPE xstring, i_iv TYPE string, i_ivx TYPE xstring, i_key_xstring TYPE xstring, i_key TYPE string, lv_text_dec TYPE string,
*this is our encrypted text from Fiori lv_ciphertext TYPE string. 

I used “lv_ciphertext” as my input variable. You can loop in your entityset method the import table it_filter_select_options and write your key value to lv_ciphertext. It should be in upper case.

Prepare the variables in right format 

We need convert strings to xstring format to be use in Class cl_sec_sxml_writer

*>> Set KEY & IV parameters i_iv = 'ThisIs33221321OurIV1ar234567'. i_key = 'THISISOURKEY1234567WORKSTATION01'. *Convert all to xstring format i_xstring = lv_ciphertext. CALL FUNCTION 'SCMS_STRING_TO_XSTRING' EXPORTING text = i_key IMPORTING buffer = i_key_xstring EXCEPTIONS failed = 1 OTHERS = 2. IF sy-subrc <> 0.
* Implement suitable error handling here ENDIF. CALL FUNCTION 'SCMS_STRING_TO_XSTRING' EXPORTING text = i_iv IMPORTING buffer = i_ivx EXCEPTIONS failed = 1 OTHERS = 2. IF sy-subrc <> 0.
* Implement suitable error handling here ENDIF. "Add IV to ciphertext CONCATENATE i_ivx(16) i_xstring INTO i_xstring IN BYTE MODE. 

Decrypt the “i_xstring” variable by using class “cl_sec_sxml_writer”

 IF i_xstring IS NOT INITIAL AND i_key_xstring IS NOT INITIAL AND i_ivx IS NOT INITIAL. TRY. " DECRYPT WITH AES256 ALGORITHM cl_sec_sxml_writer=>decrypt( EXPORTING ciphertext = i_xstring key = i_key_xstring algorithm = cl_sec_sxml_writer=>co_aes256_algorithm IMPORTING plaintext = lx_plaintext ). CATCH cx_sec_sxml_encrypt_error INTO DATA(oref). ENDTRY. ENDIF.

Here we got our decrypted text in xstring format in lx_plaintext. Now convert it to string.

* " convert xstring to string for output lv_text_dec = /ui2/cl_abap2json=>conv_xstring_to_string( lx_plaintext ).

Why is it important to consider encrypted data transfer?

Encrypting personal data whilst it is being transferred from one device to another provides effective protection against interception of the communication by a third party whilst the data is in transfer. It is also strongly recommended to use encrypted communication when transmitting any data over a wireless communication network (eg Wi-Fi) or when the data will pass through an untrusted network.
Data can be transferred over a non-secure communication channel yet still remain protected. The biggest advantage of this approach is, if you want to delivery some important data via oData, your data stay safe even if someone listening the network.