CL_ABAP_HMAC / CL_ABAP_MESSAGE_DIGEST¶
Compute HMAC signatures and cryptographic hash digests (SHA-256, SHA-1, MD5) for API authentication and data integrity checks.
Purpose¶
Two related classes handle cryptographic hashing in ABAP:
| Class | Use for |
|---|---|
CL_ABAP_HMAC |
HMAC (keyed hash) — API request signing, webhook verification |
CL_ABAP_MESSAGE_DIGEST |
Plain hash (no key) — checksums, fingerprints, integrity checks |
Supported algorithms¶
'SHA256', 'SHA384', 'SHA512', 'SHA1', 'MD5'
MD5 and SHA-1 are deprecated for security
MD5 and SHA-1 are cryptographically broken. Use 'SHA256' or higher for any security-relevant purpose.
These are instance methods — use GET_INSTANCE factory
Both classes must be instantiated via get_instance( ). UPDATE, GET_DIGEST, TO_STRING, TO_BASE64 etc. are called on the instance. There is no FINAL method on CL_ABAP_MESSAGE_DIGEST — use GET_DIGEST( ) or TO_STRING( ) to retrieve the result.
CL_ABAP_HMAC — keyed hash (API signing)¶
REPORT z_hmac_demo.
START-OF-SELECTION.
DATA: lv_key TYPE xstring,
lv_data TYPE xstring,
lv_hmac_b64 TYPE string,
lv_hmac_raw TYPE xstring.
" Convert key and message to xstring using instance method
DATA(lo_out_key) = cl_abap_conv_out_ce=>create( encoding = 'UTF-8' ).
lo_out_key->write( data = 'my-secret-key' ).
lv_key = lo_out_key->get_buffer( ).
DATA(lo_out_data) = cl_abap_conv_out_ce=>create( encoding = 'UTF-8' ).
lo_out_data->write( data = 'message to sign' ).
lv_data = lo_out_data->get_buffer( ).
TRY.
DATA(lo_hmac) = cl_abap_hmac=>get_instance(
if_algorithm = 'SHA256'
if_key = lv_key ).
lo_hmac->update( if_data = lv_data ).
" Get result as Base64 string
lo_hmac->final( IMPORTING ef_hmacb64string = lv_hmac_b64 ).
" Or as raw xstring:
" lo_hmac->final( IMPORTING ef_hmac = lv_hmac_raw ).
CATCH cx_abap_message_digest INTO DATA(lx).
MESSAGE lx->get_text( ) TYPE 'E'.
ENDTRY.
WRITE: / 'HMAC-SHA256 (Base64):', lv_hmac_b64.
CL_ABAP_MESSAGE_DIGEST — plain hash (no key)¶
For a single string input, CALCULATE_HASH_FOR_CHAR does everything in one call — no instance needed:
REPORT z_digest_static.
START-OF-SELECTION.
DATA lv_hash_hex TYPE string.
DATA lv_hash_b64 TYPE string.
TRY.
cl_abap_message_digest=>calculate_hash_for_char(
EXPORTING
if_algorithm = 'SHA256'
if_data = 'text to hash'
IMPORTING
ef_hashstring = lv_hash_hex
ef_hashb64string = lv_hash_b64 ).
CATCH cx_abap_message_digest INTO DATA(lx).
MESSAGE lx->get_text( ) TYPE 'E'.
ENDTRY.
WRITE: / 'SHA-256 (hex):', lv_hash_hex.
WRITE: / 'SHA-256 (b64):', lv_hash_b64.
Use the instance API when hashing data in multiple chunks via repeated UPDATE calls:
REPORT z_digest_instance.
START-OF-SELECTION.
" STRING_TO_XSTRING is a static helper on the same class
DATA(lx_data) = cl_abap_message_digest=>string_to_xstring( 'text to hash' ).
TRY.
DATA(lo_digest) = cl_abap_message_digest=>get_instance(
if_algorithm = 'SHA256' ).
lo_digest->update( if_data = lx_data ).
" Retrieve result — to_string returns hex, to_base64 returns Base64
DATA(lv_hash_hex) = lo_digest->to_string( ).
DATA(lv_hash_b64) = lo_digest->to_base64( ).
CATCH cx_abap_message_digest INTO DATA(lx).
MESSAGE lx->get_text( ) TYPE 'E'.
ENDTRY.
WRITE: / 'SHA-256 (hex):', lv_hash_hex.
WRITE: / 'SHA-256 (b64):', lv_hash_b64.
Verify a webhook signature¶
REPORT z_webhook_verify.
START-OF-SELECTION.
" Simulate incoming webhook header: X-Signature: sha256=<base64value>
DATA lv_header_value TYPE string VALUE 'sha256=abc123base64value=='.
DATA lv_raw_body TYPE string VALUE 'webhook payload body'.
DATA lv_secret TYPE string VALUE 'my-webhook-secret'.
" Strip 'sha256=' prefix (7 characters) from received signature
DATA(lv_received_sig) = lv_header_value+7.
" Compute HMAC on the raw body
DATA(lo_out_key) = cl_abap_conv_out_ce=>create( encoding = 'UTF-8' ).
lo_out_key->write( data = lv_secret ).
DATA(lx_key) = lo_out_key->get_buffer( ).
DATA(lo_out_body) = cl_abap_conv_out_ce=>create( encoding = 'UTF-8' ).
lo_out_body->write( data = lv_raw_body ).
DATA(lx_body) = lo_out_body->get_buffer( ).
DATA lv_computed_sig TYPE string.
TRY.
DATA(lo_hmac) = cl_abap_hmac=>get_instance(
if_algorithm = 'SHA256'
if_key = lx_key ).
lo_hmac->update( if_data = lx_body ).
lo_hmac->final( IMPORTING ef_hmacb64string = lv_computed_sig ).
CATCH cx_abap_message_digest INTO DATA(lx).
MESSAGE lx->get_text( ) TYPE 'E'.
RETURN.
ENDTRY.
IF lv_computed_sig = lv_received_sig.
WRITE: / 'Signature valid — process webhook'.
ELSE.
WRITE: / 'Signature mismatch — reject request'.
WRITE: / 'Received: ', lv_received_sig.
WRITE: / 'Computed: ', lv_computed_sig.
ENDIF.
See also¶
CL_ABAP_CONV_OUT_CE— string to xstring conversion needed for input