2022 Feb 24 7:29 AM
FIrst of all I'm sorry, somehow my previous question is deleted (I think accidently because of duplicate comments), I have to repost this question.
I've been looking for a way to verify JWT token signature from ABAP(RS256 algorithm is used). I've found this FM : SSFW_KRN_VERIFY, but still no luck, I always get crc = 5 (AFAIK result should be crc = 0 => meaning verified )
and after checking SM21 i got : SSF : Sign Return Code 026, (26 SSF signer/recipient list: No certificate)
Am I missing some step here, I thought we don't need certificate just to validate the signature.
can anybody show me some example on how to use it? thanks a lot mate. cheers.
here is the JWT (header.payload.signature):
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Il82SnJ5U2hQU0dpTjdZMHBGMFBaYkZMamxzUVVSalRCdUs4a3kwYUVhY28ifQ.eyJleHAiOjE2NDU1MTMwNTQsIm5iZiI6MTY0NTUwOTQ1NCwidmVyIjoiMS4wIiwiaXNzIjoiaHR0cHM6Ly9hc3RyYWFjY291bnRkZXYuYjJjbG9naW4uY29tL2FmODljNzBhLWQwNTItNDQ1NC1hMDAxLTI3NzA4ZmY5ZjI4YS92Mi4wLyIsInN1YiI6IjAyMGYyMGI2LTE5NTEtNDU2Ny1iYTRkLWY5NzI0NThiZTY2NSIsImF1ZCI6IjRhZTU0Yjg0LTdiZjAtNDBkOC04NDk3LTQ2YmUxYjU5MjdiNyIsImFjciI6ImIyY18xYV9zaWdudXBfc2lnbmluIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjE2NDU1MDk0NTQsImF1dGhfdGltZSI6MTY0NTUwOTQ1NCwiZW1haWwiOiJqb2VreS5oYXJ0YW50b0BhaS5hc3RyYS5jby5pZCIsIm5hbWUiOiJKb2VreSBIYXJ0YW50byIsInRpZCI6IjVhMGI4NmUxLTNhZjctNGQxNi1hNjNlLWFmZTU1YmVhYjc5NSIsImlzRm9yZ290UGFzc3dvcmQiOmZhbHNlLCJwYXNzd29yZEV4cGlyZWQiOmZhbHNlfQ.ayeSfPKbQ7Aq7IauKXImBK0-2hdXIuQm_vtTef53icHTr8ErVr_lKb11T5OWa-UQb0EG0hhUQ0SFyVy7OY-RrLPL2wDw9bhDM1LZr97vnGVAqOIykavqxLz7r_a4HFfOrSiVFg1QdiO-FiWruQr35WHOwdQ698Vf8eTgZb1GWXR_RtmIQ_NjGR9Sg2WHL2C-yGKDPlJr9AAV7jyXU0GQYu2Yy2TvVZEOA_3APIZ2tF2vk_q4wsfHfPPi7D9ZJDX31b5Ki3h81rhZ66GCZ02NYE6d4fyBRJAJX9HFUFxby9yFjLsEvNotGRAS3Nu2Nln0YivIx1f8v70VCVlNOTpTTA
and this is the sample public key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr9+wJCEv4K1DQUUWKEPq
H6daTt6jXPoNu3h8TmbX1Hyk2HAjKGBMF4fzPXNcGIqP9DXtwR7VqlzyA5zT6z6J
n3ZJOYG5VIC8RV8u/NsomX8qyaBVmAlZwTxJvCXU0DnFa1g0EDe1y4gMcXZQMlis
HF5kt2l3C9muebQmSSW699D0J27+DZSQb+0AbUeqRPfMMJsaa6+h2nDnT45jBFqy
xx/w3cdajfp0+6TutE8RAg5E82Aoc+NGbIvyyblsoDSMF+CQIe+r4buFYqi63pGk
JZrbFNwz8R+VLElpcxgTlmJpe5+Wxksabq5rAZ6U3YH4IXGSpVKpSt9+nh3RBdDFcQIDAQAB
-----END PUBLIC KEY-----
here is how I call the fm
*&---------------------------------------------------------------------*
*& Report Y_TEST_RSASHA256_2
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT y_test_rsasha256_2.
DATA: lf_crc TYPE ssfreturn.
DATA: lf_output TYPE xstring.
DATA: lf_cert TYPE xstring.
DATA: lf_signing_input_x TYPE xstring.
DATA: lf_signing_ouput_x TYPE xstring.
DATA: lf_signing_ouput TYPE xstring.
DATA: lf_signing_input TYPE string.
DATA: lf_signing_input_h TYPE string.
DATA: lf_signing_input_h_j TYPE string.
DATA: lf_signing_input_p TYPE string.
DATA: lf_signing_input_p_j TYPE string.
DATA: lv_base64 TYPE string.
DATA: lf_signer TYPE ssfinfo.
DATA: lt_signer TYPE STANDARD TABLE OF ssfinfo." WITH HEADER LINE.
"tried to validate from https://8gwifi.org/rsasignverifyfunctions.jsp
"signature verification passed
"jwt header.payload.
CONCATENATE
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Il82SnJ5U2hQU0dpTjdZ'
'MHBGMFBaYkZMamxzUVVSalRCdUs4a3kwYUVhY28ifQ.eyJleHAiOjE2NDU1MTMwN'
'TQsIm5iZiI6MTY0NTUwOTQ1NCwidmVyIjoiMS4wIiwiaXNzIjoiaHR0cHM6Ly9hc'
'3RyYWFjY291bnRkZXYuYjJjbG9naW4uY29tL2FmODljNzBhLWQwNTItNDQ1NC1hM'
'DAxLTI3NzA4ZmY5ZjI4YS92Mi4wLyIsInN1YiI6IjAyMGYyMGI2LTE5NTEtNDU2N'
'y1iYTRkLWY5NzI0NThiZTY2NSIsImF1ZCI6IjRhZTU0Yjg0LTdiZjAtNDBkOC04N'
'Dk3LTQ2YmUxYjU5MjdiNyIsImFjciI6ImIyY18xYV9zaWdudXBfc2lnbmluIiwib'
'm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjE2NDU1MDk0NTQsImF1dGhfdGltZ'
'SI6MTY0NTUwOTQ1NCwiZW1haWwiOiJqb2VreS5oYXJ0YW50b0BhaS5hc3RyYS5jb'
'y5pZCIsIm5hbWUiOiJKb2VreSBIYXJ0YW50byIsInRpZCI6IjVhMGI4NmUxLTNhZ'
'jctNGQxNi1hNjNlLWFmZTU1YmVhYjc5NSIsImlzRm9yZ290UGFzc3dvcmQiOmZhb'
'HNlLCJwYXNzd29yZEV4cGlyZWQiOmZhbHNlfQ'
INTO lf_signing_input.
"this part to convert to json
SPLIT lf_signing_input AT '.' INTO lf_signing_input_h lf_signing_input_p.
"get json format
PERFORM f_decode_j USING lf_signing_input_h
CHANGING lf_signing_input_h_j.
"get json format
PERFORM f_decode_j USING lf_signing_input_p
CHANGING lf_signing_input_p_j.
"end part convert to json
DATA :
ld_sign_comp TYPE string,
ld_sign_comp_x TYPE xstring
.
"signature
CONCATENATE
'ayeSfPKbQ7Aq7IauKXImBK0-2hdXIuQm_vtTef53icHTr8ErVr_lKb1'
'1T5OWa-UQb0EG0hhUQ0SFyVy7OY-RrLPL2wDw9bhDM1LZr97vnGVAqO'
'IykavqxLz7r_a4HFfOrSiVFg1QdiO-FiWruQr35WHOwdQ698Vf8eTgZ'
'b1GWXR_RtmIQ_NjGR9Sg2WHL2C-yGKDPlJr9AAV7jyXU0GQYu2Yy2Tv'
'VZEOA_3APIZ2tF2vk_q4wsfHfPPi7D9ZJDX31b5Ki3h81rhZ66GCZ02'
'NYE6d4fyBRJAJX9HFUFxby9yFjLsEvNotGRAS3Nu2Nln0YivIx1f8v7'
'0VCVlNOTpTTA'
INTO ld_sign_comp.
"convert from base64 url to base64
REPLACE ALL OCCURRENCES OF '-' IN ld_sign_comp WITH '+'.
REPLACE ALL OCCURRENCES OF '_' IN ld_sign_comp WITH '/'.
"get payload binary
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = lf_signing_input
IMPORTING
buffer = lf_signing_input_x.
"get signature binary
CALL FUNCTION 'SSFC_BASE64_DECODE'
EXPORTING
b64data = ld_sign_comp
IMPORTING
bindata = ld_sign_comp_x.
DATA lv_result_code TYPE i.
DATA lt_signer_info TYPE TABLE OF ssfinfo.
DATA :
ld_pub_key TYPE string,
ld_pub_key_x TYPE xstring
.
CONCATENATE
* '-----BEGIN PUBLIC KEY-----' tried add or remove this still no luck
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr9+wJCEv4K1DQUUWKEPq'
'H6daTt6jXPoNu3h8TmbX1Hyk2HAjKGBMF4fzPXNcGIqP9DXtwR7VqlzyA5zT6z6J'
'n3ZJOYG5VIC8RV8u/NsomX8qyaBVmAlZwTxJvCXU0DnFa1g0EDe1y4gMcXZQMlis'
'HF5kt2l3C9muebQmSSW699D0J27+DZSQb+0AbUeqRPfMMJsaa6+h2nDnT45jBFqy'
'xx/w3cdajfp0+6TutE8RAg5E82Aoc+NGbIvyyblsoDSMF+CQIe+r4buFYqi63pGk'
'JZrbFNwz8R+VLElpcxgTlmJpe5+Wxksabq5rAZ6U3YH4IXGSpVKpSt9+nh3RBdDF'
'cQIDAQAB'
* '-----END PUBLIC KEY-----'
INTO ld_pub_key.
"get public key binary
CALL FUNCTION 'SSFC_BASE64_DECODE'
EXPORTING
b64data = ld_pub_key
IMPORTING
bindata = ld_pub_key_x.
CALL FUNCTION 'SSFW_KRN_VERIFY'
EXPORTING
ssftoolkit = 'SAPSECULIB'
str_format = 'PKCS1-V1.5'
b_inenc = ' '
b_outdec = ' '
str_pab = '<no_certificate_check>'
str_pab_password = ' '
ostr_signed_data = ld_sign_comp_x "signed data converted to xstring SSFC_BASE64_DECODE
ostr_input_data = lf_signing_input_x "input data converted to xstring SCMS_STRING_TO_XSTRING
str_hashalg = 'SHA256'
str_chainfmt = 'X509v3'
ostr_chain_data = ld_pub_key_x "public key converted to xstring SSFC_BASE64_DECODE
IMPORTING
crc = lv_result_code "result 5 (not verified?)
TABLES
signer_result_list = lt_signer_info
* CERTIFICATELIST =
EXCEPTIONS
ssf_krn_error = 1
ssf_krn_noop = 2
ssf_krn_nomemory = 3
ssf_krn_opinv = 4
ssf_krn_nossflib = 5
ssf_krn_input_data_error = 6
ssf_krn_invalid_par = 7
ssf_krn_invalid_parlen = 8
ssf_fb_input_parameter_error = 9
OTHERS = 10.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
FORM f_decode_j USING ld_string TYPE string
CHANGING ld_dec_string TYPE string.
DATA :
ld_xstring TYPE xstring,
ld_len TYPE i,
lt_binary TYPE STANDARD TABLE OF sdokcntbin
.
CALL FUNCTION 'SCMS_BASE64_DECODE_STR'
EXPORTING
input = ld_string
* UNESCAPE = 'X'
IMPORTING
output = ld_xstring
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = ld_xstring
* APPEND_TO_TABLE = ' '
IMPORTING
output_length = ld_len
TABLES
binary_tab = lt_binary.
CALL FUNCTION 'SCMS_BINARY_TO_STRING'
EXPORTING
input_length = ld_len
* FIRST_LINE = 0
* LAST_LINE = 0
* MIMETYPE = ' '
* ENCODING =
IMPORTING
text_buffer = ld_dec_string
* OUTPUT_LENGTH =
TABLES
binary_tab = lt_binary
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
ENDFORM.
2022 May 31 10:49 AM
Hi profjoe93,
actually it is possible to create/modify dummy cert from the public key.
With an ASN.1 editor like this one. Open the key and the cert files and replace the key in the cert.
Here I used your key and my cert from above.
Then use the resulting cert, which for your key is this one. The verification will succeed.
CONCATENATE
'MIIDATCCAemgAwIBAgIUBMjxGU+uogZ+0xgtJhvOz+917Y0wDQYJKoZIhvcNAQEL'
'BQAwEDEOMAwGA1UEAwwFdXNlcjEwHhcNMjIwMjIzMDczMDE5WhcNMzIwMjIxMDcz'
'MDE5WjAQMQ4wDAYDVQQDDAV1c2VyMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC'
'AQoCggEBAK/fsCQhL+CtQ0FFFihD6h+nWk7eo1z6Dbt4fE5m19R8pNhwIyhgTBeH'
'8z1zXBiKj/Q17cEe1apc8gOc0+s+iZ92STmBuVSAvEVfLvzbKJl/KsmgVZgJWcE8'
'Sbwl1NA5xWtYNBA3tcuIDHF2UDJYrBxeZLdpdwvZrnm0JkkluvfQ9Cdu/g2UkG/t'
'AG1HqkT3zDCbGmuvodpw50+OYwRasscf8N3HWo36dPuk7rRPEQIORPNgKHPjRmyL'
'8sm5bKA0jBfgkCHvq+G7hWKout6RpCWa2xTcM/EflSxJaXMYE5ZiaXuflsZLGm6u'
'awGelN2B+CFxkqVSqUrffp4d0QXQxXECAwEAAaNTMFEwHQYDVR0OBBYEFDMYiI+n'
'v4OQzd7TXVSJ6VFjGdrZMB8GA1UdIwQYMBaAFDMYiI+nv4OQzd7TXVSJ6VFjGdrZ'
'MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACofjjLfxmis77D4'
'vuZ1hSsgfcKQrKjeM+P7Q2WznOzlHe1CvysKJ8O/u6PgbUqrYuFFAcqP9+tD32fZ'
'B9aVOt86JtNxf/1uP1gkzLxxKCzwVDjlqMcV497eTLg3RgRby38Tpe3pfybwxhHa'
'1nIaPU0toVympvVroVS6CwVGmRqNt+YaEDDHq5JlZ9RlFPxiePuZNx/3L8GNt26X'
'skAC5RrZayVD6dK3DJFt2ROKmYg/KFrfs+0k1Qycj/V9DHp6p7dGcDAiBUJ2JFe6'
'/2dmeVwUy2Tt95HdxqEIOH6Nk0YK74CmNqxcLXoDkgoYOCkJoOTCH4Ih6+hXPlB3'
'd570iZk='
INTO ld_pub_key. " pub key wrapped in cert