Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
monalisa_biswal
Contributor
42,056

Introduction


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( ).

 

Decryption


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.

Encryption:


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.

Sample Output:


EXAMPLE:
Text: Test AES@CBC#PKCS$5
Encrypted Text : B8Q1+w5vH9jG3V/ejYg5igeGNgfX6nvqUGrDnogyDdo=
After Decryption : Test AES@CBC#PKCS$5

Conclusion


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.
28 Comments
Sandra_Rossi
Active Contributor
Interesting post, thank you! Little typoS for CL_ABAP_XML_WRITER -> CL_SEC_SXML_WRITER (or are there some subclasses). Do you know what ABAP release it requires?

 
monalisa_biswal
Contributor
Thanks Sandra. Yes, The class is CL_SEC_SXML_WRITER and corrected the names in the blog.

I am not sure what is the minimum release required for this class? But it is part of BC-SEC Application component and SAP-BASIS software component. We have release 740 SP 20 for this component in our system.
larshp
Active Contributor
https://github.com/Sumu-Ning/AES is also a possibility, with support for

"

  • Encryption mode: ECB, CBC, PCBC, CFB, OFB, CTR.

  • Padding standard: None, PKCS #5, PKCS #7


"
koehntopp
Product and Topic Expert
Product and Topic Expert
larshp
Active Contributor
True, I wish SAP would support all the basic algorithms on also old versions. Having a bit of encryption is better than nothing. Also is above released for customer use? Using the secure store is not allowed for customers?
Jelena_Perfiljeva
Active Contributor
Nice post! To the point and the example is described well.
monalisa_biswal
Contributor
0 Kudos
Thanks Jelena 🙂
What is the reason for 16 bit padding from XSTRING?
0 Kudos

Hi Monalisa,

 

How to download the key as ascii file or PGP public key block? and can you recommend how to set the validity?

0 Kudos
Any article on RSA/ECB/PKCS1Encryption in ABAP?
0 Kudos
Hello Monalisa,

Thanks for the AES content!

I am trying to use the Decryption logic.

Error analysis
An exception has occurred which is explained in more detail below. The
an exception is assigned to class 'CX_SEC_SXML_ENCRYPT_ERROR' and was not caught
in procedure
"DECRYPT" "(METHOD)", nor was it propagated by a RAISING clause.
Since the caller of the procedure could not have anticipated this
exception, the current program was terminated.
The reason for the exception is:
Error when decrypting XML data

UNCAUGHT_EXCEPTION CX_SEC_SXML_ENCRYPT_ERROR CL_SEC_SXML_WRITER============CP 12

Regards,

Raja
mynynachau
Community Advocate
Community Advocate
0 Kudos
For the benefit of all SAP Community members having similar questions, please post your question here: https://answers.sap.com/questions/ask.html That way, your question is addressed with all related experts within SAP Community and your answered question can be found and be helpful for others in future.

Have a look at our tutorial for asking and answering questions in SAP Community: https://developers.sap.com/tutorials/community-qa.html

Best regards

Mynyna (SAP Community moderator)
0 Kudos
Hi Monalisa,

I am trying to decrypt with the below key using the method "cl_sec_sxml_writer=>decrypt"  and the data is stored in the file

 

random TYPE string VALUE 'Ut3AvBQbD6AbuMZZMmhA7w6C4zxrN9rD2J8ZKbxpaoM='.

 

DATA(lr_conv_keycl_abap_conv_out_ce=>create).
lr_conv_key->writedata random ).

DATA(lv_keylr_conv_key->get_buffer).

DATA(lr_conv_datacl_abap_conv_out_ce=>create).
lr_conv_data->writedata gs_data-data ).

 

cl_sec_sxml_writer=>decrypt(
EXPORTING
ciphertext lv_data
key lv_key
algorithm =  cl_sec_sxml_writer=>co_aes256_algorithm
IMPORTING
plaintext =  DATA(lv_message_decrypted).

 

I am getting the dump at the method - Decrypt. - CX_SEC_SXML_ENCRYPT_ERROR

 

regards,

Rajesh Velaga
joaquin11
Member
0 Kudos
the external system how should the encrypted string send?
sourav2117
Participant
0 Kudos
Hi Ma'am,

Will it work for RSA Algorithm(RSA/ECB/PKCS1 PADDING).

Can you please help me on this.

 
former_member694960
Discoverer
0 Kudos
Hi Rajesh,

I am also getting the same error. is this solved for you? if so, please explain me the steps.

 

Best Regards,

Sanjay Naik
former_member721951
Discoverer
0 Kudos

Hi Saurav,

 

can you provide your contact number??

Please connect with me via SAP Community so that we can exchange a direct message.

0 Kudos
HI  Monalisa,

Did you find any alternative solution for RSA encryption?
Former Member
This Prevention Agreement must be the reason, why all the Secstore, SSFS DAT and Key files are still DES-EDE encrypted.
lucy
Explorer
0 Kudos
Hello experts,

I'm looking for a way to make the encryption of JSON data with AES/ECB/PKCS#5Padding   in SAP PO7.5 receiving REST adapter, anyone could share me any experience or information or any advice? Appreciate for your information!

Thanks!

Lucy
stag_pune
Explorer

per note 2972991 - 'Neither the class CL_SEC_SXML_WRITER nor its methods , including the whole SEC_SXML package and SSF functions for en-/decryption are released for customer usage.
All existing functions and methods exist exclusively for legal business requirements of SAP genuine applications and original for web service security (SOAP).'

Also this note https://launchpad.support.sap.com/#/notes/3074516 

stag_pune
Explorer

I wrote UDF for that with pretty easy JAVA code.. but I needed to encrypt only couple of fields. You can also write custom adapter module and call it in sequence to encrypt the payload. Not sure if SAP has standard adapter modules for AES, it does have for PGP. See if any of those options work for you.

marco_hammel2
Participant

Hi monalisa.biswal ,
I came across your blog post by accident. As part of my job I'm doing code reviews for software including ABAP. I can bet there are many more developers out there just taking benefit from your write up. Sharing your experience is great, however I ask you to be cautiousness, at least when it comes to crypto because people start to copy them without thinking.
I see some to the typical top 10 mistakes in your example implementation you can find here https://littlemaninmyhead.wordpress.com/2017/04/22/top-10-developer-crypto-mistakes/

Most prominently: The initialization vector is not a key or part of the key. It needs to be a random value, as otherwise chosen plaintext attacks on the cryptographic implementation become practical no matter the key size. I'd kindly ask you to fix this in your example implementation or put a disclaimer in there to give other developers the chance to not copy the mistake.

BR

Marco

matt
Active Contributor

The encryption/decryption was done with a common key which gets generated in SAP and shared through automated email from the system.

Hmm. I guess doing it this way will mean that if you lose the key you can always ask on the dark web. Email is inherently insecure. Unless it's encrypted of course... 

0 Kudos
Hi all,

I got a convertion error when I try to convert xstring to string after use cl_sec_sxml_writer=>decrypt. The message say about error from 4110 to 4103.

I can not solve that with any convertion utility.

Can any one help me with that error? I am very interested in decrypt in memory

Juan
beyhan_meyrali
Active Participant

Hi thanks for sharing.

And In case if someone needs whole code as class.

 

CLASS zcl_encryption DEFINITION
  PUBLIC
  CREATE PUBLIC .

  PUBLIC SECTION.
    METHODS:
      get_key
        RETURNING VALUE(e_key) TYPE xstring.  " Method to generate encryption key

    METHODS encrypt_text
      IMPORTING
                i_text            TYPE string  " Plain text to be encrypted
                i_key_xstring     TYPE xstring " Encryption key in xstring format
      RETURNING VALUE(e_text_enc) TYPE string. " Encrypted Base64 encoded string

    METHODS decrypt_text
      IMPORTING
                i_encoded_text    TYPE string  " Base64 encoded string to be decrypted
                i_key_xstring     TYPE xstring " Encryption key in xstring format
      EXPORTING
                err_text          TYPE string
      RETURNING VALUE(e_text_dec) TYPE string. " Decrypted string

    METHODS usage_sample
      IMPORTING
                i_text            TYPE string
      EXPORTING
                e_text_enc        TYPE string
                err_text          TYPE string
                e_key             TYPE xstring
      RETURNING VALUE(e_text_dec) TYPE string. " Decrypted string

  PRIVATE SECTION.
    CONSTANTS: c_iv TYPE xstring VALUE '00000000000000000000000000000000'.

ENDCLASS.



CLASS ZCL_ENCRYPTION IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ENCRYPTION->DECRYPT_TEXT
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_ENCODED_TEXT                 TYPE        STRING
* | [--->] I_KEY_XSTRING                  TYPE        XSTRING
* | [<---] ERR_TEXT                       TYPE        STRING
* | [<-()] E_TEXT_DEC                     TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD decrypt_text.
    DATA lv_xstring   TYPE xstring.

    " Decode the Base64 encoded input text
    IF i_encoded_text IS NOT INITIAL.
      CALL FUNCTION 'SCMS_BASE64_DECODE_STR'
        EXPORTING
          input  = i_encoded_text
        IMPORTING
          output = lv_xstring.

      IF sy-subrc <> 0 OR lv_xstring IS INITIAL.
        " Handle Base64 decoding failure
        err_text = 'Base64 decoding failed'.
        RETURN.
      ENDIF.
    ELSE.
      " Handle the case where input text is empty
      err_text = 'Input text is empty'.
      RETURN.
    ENDIF.

    " Proceed with decryption if the xstring is not empty
    IF lv_xstring IS NOT INITIAL.
      TRY.

          " Add 16-byte padding before decryption
          CONCATENATE c_iv(16) lv_xstring INTO lv_xstring IN BYTE MODE.

          " Decrypt the ciphertext
          DATA: lv_message_decrypted TYPE xstring.
          cl_sec_sxml_writer=>decrypt(
            EXPORTING
              ciphertext = lv_xstring
              key        = i_key_xstring
              algorithm  = cl_sec_sxml_writer=>co_aes256_algorithm_pem
            IMPORTING
              plaintext  = lv_message_decrypted ).

          " Convert the decrypted xstring to a 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).
          " Handle decryption errors
          err_text = 'Decryption failed: ' && oref->get_longtext( ).
      ENDTRY.
    ELSE.
      " Handle the case where the xstring is empty after decoding
      err_text = 'Decoded xstring is empty'.
    ENDIF.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ENCRYPTION->ENCRYPT_TEXT
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_TEXT                         TYPE        STRING
* | [--->] I_KEY_XSTRING                  TYPE        XSTRING
* | [<-()] E_TEXT_ENC                     TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD encrypt_text.
    DATA: lv_xstring  TYPE xstring,
          lv_message  TYPE xstring,
          lr_conv_sec TYPE REF TO cl_abap_conv_out_ce,
          lr_xstring  TYPE xstring.

    " Convert plain text to xstring
    lr_conv_sec = cl_abap_conv_out_ce=>create( ).
    lr_conv_sec->write( data = i_text ).
    lv_xstring = lr_conv_sec->get_buffer( ).


    " Encrypt the xstring using AES-256 algorithm
    cl_sec_sxml_writer=>encrypt_iv(
      EXPORTING
        plaintext  = lv_xstring
        key        = i_key_xstring
        algorithm  = cl_sec_sxml_writer=>co_aes256_algorithm_pem
        iv         = c_iv
      IMPORTING
        ciphertext = lv_message ).

    " Remove the 16-byte padding before encoding
    lr_xstring = lv_message+16.

    " Encode the result as Base64
    CALL FUNCTION 'SCMS_BASE64_ENCODE_STR'
      EXPORTING
        input  = lr_xstring
      IMPORTING
        output = e_text_enc.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ENCRYPTION->GET_KEY
* +-------------------------------------------------------------------------------------------------+
* | [<-()] E_KEY                          TYPE        XSTRING
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD get_key.
    DATA: random      TYPE xstring,
          lr_conv_key TYPE REF TO cl_abap_conv_out_ce.

    " Generate a random key using AES-256 algorithm
    CALL METHOD cl_sec_sxml_writer=>generate_key
      EXPORTING
        algorithm = cl_sec_sxml_writer=>co_aes256_algorithm
      RECEIVING
        key       = random.

    " Convert the key to a string format
    lr_conv_key = cl_abap_conv_out_ce=>create( ).
    lr_conv_key->write( data = random ).
    e_key = lr_conv_key->get_buffer( ).
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ENCRYPTION->USAGE_SAMPLE
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_TEXT                         TYPE        STRING
* | [<---] E_TEXT_ENC                     TYPE        STRING
* | [<---] ERR_TEXT                       TYPE        STRING
* | [<---] E_KEY                          TYPE        XSTRING
* | [<-()] E_TEXT_DEC                     TYPE        STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD usage_sample.

    e_key = get_key( ).

    encrypt_text(
      EXPORTING
        i_text        = i_text
        i_key_xstring = e_key
      RECEIVING
        e_text_enc    = e_text_enc
    ).

    decrypt_text(
      EXPORTING
        i_encoded_text = e_text_enc
        i_key_xstring  = e_key
      IMPORTING
        err_text       = err_text
      RECEIVING
        e_text_dec     = e_text_dec
    ).

  ENDMETHOD.
ENDCLASS.

 

EshaR
Discoverer
0 Kudos

Hello @monalisa_biswal 

 

Thank you for this blog post, it was very helpful. However, we have a business requirement where the need to do this encoding WITHOUT the IV. Any pointers on this will be helpful. 

Wolfgang_Janzen
Product and Topic Expert
Product and Topic Expert

Kindly notice that this Blog post is not an official SAP post.

Up to now, there's no API available in ABAP systems for performing cryptographic operations (such as data encryption / decryption plus the required proper storage of the keys) since such are subject of export control regulations.

We consider to change that in the future (i.e. providing such APIs in conjunction with a proper key handling/storage); but in the moment I'm unable to provide an estimated availability date.

Kind regards,
Wolfgang Janzen
(Product Owner for the product area "ABAP Security")

 

Labels in this area