示例 在 ABAP 中使用自己的 RSA 实现 RSA Encryption in ABAP

在下面的程序中,我们使用公钥加密并使用私钥签名此消息“32字节秘密消息!”。 结果显示在屏幕上。 它们保存在我们生成密钥以在 SAP 外部检查它们的同一文件夹中。 签名通常涉及对消息进行哈希处理并对哈希进行签名,因为我们的消息足够小,所以我们跳过哈希并对消息本身进行签名。 作为概念证明应该足够了。

示例 在 ABAP 中使用自己的 RSA 实现 RSA Encryption in ABAP

 

REPORT Z_RSA.

data: bi1     type ref to z04_BigIntX,
      bi2     type ref to z04_BigIntX,
      bi256   type ref to z04_BigIntX,

      s  type string,

      i1 type I,
      i2 type I,
      i3 type I value 0,

      x1 type X,

      publicExponent   type ref to z04_BigIntX,

      pub_modulus_s    type string,
      pub_modulus_x    type xstring,
      pub_modulus_bi   type ref to z04_BigIntX,

      priv_exponent_s  type string,
      priv_exponent_x  type xstring,
      priv_exponent_bi type ref to z04_BigIntX,

      msg_text         type string,
      msg_plain_bi     type ref to z04_BigIntX,
      msg_encr_bi      type ref to z04_BigIntX,
      msg_encr_x       type xstring,
      msg_sign_x       type xstring,

      pkcs_rnd         type xstring,
      pkcs_ff_s        type string,
      pkcs_ff_x        type xstring,
      pkcs_head_sign   type xstring value '0001',
      pkcs_head_encr   type xstring value '0002',
      pkcs_zero        type xstring value '00',
      pkcs_one         type xstring value '01',
      msg_xstr         type xstring,
      msg_xstr_e       type xstring,
      msg_xstr_s       type xstring,

      msg_file_name    type string value '/tmp/rsa/encrypted_msg',
      msg_file_name_s  type string value '/tmp/rsa/signed_msg'.

create object msg_plain_bi.
create object bi1.
create object bi2.
create object bi256.
create object publicExponent.
create object pub_modulus_bi.
create object priv_exponent_bi.
create object msg_encr_bi.


DATA: T1 TYPE I, T2 TYPE I, T3 TYPE I.

bi256->seti( 256 ).

*---------------------
* PREPARE THE KEY
*---------------------

" public exponent
publicExponent->setstr( '65537' ).

" private exponent
CONCATENATE
  '00:bd:bb:fe:db:7e:14:48:44:73:29:90:96:24:bf:'
  '8a:7e:92:5a:41:a7:06:cd:71:c0:a4:54:5c:43:2e:'
  'bf:10:8a:a1:6a:9b:cc:88:d9:6a:4a:29:22:5b:9f:'
  '54:24:fc:cc:ca:b0:de:2e:3f:d7:14:46:2b:e9:3c:'
  '69:88:cd:2a:2e:df:78:a6:48:e0:50:a3:44:5d:bf:'
  '8a:ef:76:bd:6e:f0:5e:4c:24:9c:89:6b:07:a8:1a:'
  'be:15:69:e7:ef:5d:9c:b6:e2:8d:93:21:72:c3:ae:'
  '91:fc:96:61:a8:9f:11:77:68:be:08:10:c4:6c:3f:'
  'de:c8:b2:a3:15:f2:cb:1c:9d:3d:20:75:59:ff:8b:'
  '75:9d:44:39:36:84:7e:4d:fe:96:01:29:11:4c:dd:'
  '15:33:44:0b:f8:f0:ad:02:62:5f:34:81:fa:73:f9:'
  '6c:1d:00:cf:79:0c:71:b8:71:c1:ad:35:84:05:32:'
  '95:70:8d:b6:7a:d1:26:fd:2c:32:f4:09:3b:2e:7d:'
  '80:18:e2:3e:7d:c6:5b:ad:ad:f0:a7:ff:92:6d:c8:'
  '94:34:4a:13:b8:7d:c5:81:02:69:f4:1a:6d:a5:d1:'
  'd2:ae:ac:c1:7d:3d:62:97:4a:28:11:07:60:b1:3d:'
  '02:ba:5a:98:9b:49:60:fb:65:03:65:d2:be:c7:c1:'
  'aa:41'
into priv_exponent_s.
replace ALL OCCURRENCES OF REGEX '(:)' in priv_exponent_s with ''.
TRANSLATE priv_exponent_s TO UPPER CASE.
priv_exponent_x = priv_exponent_s.
" Convert the modulus from HEX to DEC
bi2->seti( 1 ).
i1 = xstrlen( priv_exponent_x ).
WHILE ( i1 > 0 ).
  i1 = i1 - 1.
  i2 = priv_exponent_x+i1(1).
  bi1->seti( i2 ).
  bi1->mul( bi2 ).
  bi2->mul( bi256 ).
  priv_exponent_bi = priv_exponent_bi->add( bi1 ).
ENDWHILE.

" public key
CONCATENATE
  '00:e2:05:b9:ed:b7:8c:24:f3:4e:d0:07:38:74:81:'
  'dc:30:5c:5c:b1:7b:5f:da:e3:57:43:65:e7:a4:83:'
  '10:b9:a7:ae:3d:07:5a:53:e8:5b:7b:3f:a7:92:99:'
  '9a:83:75:9e:ad:d3:82:69:cc:07:72:1e:3c:e3:d8:'
  '33:0f:b7:a5:69:02:45:f2:69:04:97:2c:77:7b:74:'
  'a5:98:9f:0d:9b:fd:a9:16:a6:d7:7b:eb:5c:f1:f6:'
  '82:18:d6:d1:f3:d3:2e:15:6d:f9:17:d3:2b:7b:17:'
  '0b:cf:8d:42:ba:5d:fa:5c:c9:8c:a6:27:52:8c:98:'
  '6f:d4:86:c2:04:34:bc:61:69:4e:7a:fe:09:ca:76:'
  '5d:35:5d:37:0a:7b:e2:64:06:9b:f4:d9:da:70:f9:'
  'bc:3a:04:4d:f8:db:51:57:16:64:a9:a1:db:80:1c:'
  '0f:3f:96:6f:bd:53:a3:ea:76:fc:54:e8:80:c1:d7:'
  'a9:f9:5f:be:08:c9:40:93:42:c3:16:ed:74:20:6b:'
  '0d:dc:a9:55:93:62:28:14:b1:91:5b:1c:f1:1d:75:'
  'f9:02:64:33:5f:4a:87:66:45:df:96:65:3b:82:46:'
  '30:fa:f8:af:fd:f8:ad:63:ec:a9:38:6b:62:cc:0b:'
  'ba:f4:6c:f3:88:61:ca:d6:fb:45:42:fb:29:22:cf:'
  'c4:13'
into pub_modulus_s.
replace ALL OCCURRENCES OF REGEX '(:)' in pub_modulus_s with ''.
TRANSLATE pub_modulus_s TO UPPER CASE.
pub_modulus_x = pub_modulus_s.
" Convert the modulus from HEX to DEC
bi2->seti( 1 ).
i1 = xstrlen( pub_modulus_x ).
WHILE ( i1 > 0 ).
  i1 = i1 - 1.
  i2 = pub_modulus_x+i1(1).
  bi1->seti( i2 ).
  bi1->mul( bi2 ).
  bi2->mul( bi256 ).
  pub_modulus_bi = pub_modulus_bi->add( bi1 ).
ENDWHILE.

*---------------------
* END PREPARE THE KEY
*---------------------

msg_text = 'Thirty-two bytes secret message!'.
write: / 'Plain message:'.
write: / msg_text.
SKIP.

*---------------------
* START ENCRYPTION
*---------------------

CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
  EXPORTING
    text = msg_text
  IMPORTING
    buffer = msg_xstr.

write: / 'Plain message in HEX:'.
PERFORM SHOW_DATA USING msg_xstr.
SKIP.

i1 = 256 - 3 - xstrlen( msg_xstr ).

CALL FUNCTION 'GENERATE_SEC_RANDOM'
  EXPORTING
    length = i1
  IMPORTING
    random = pkcs_rnd
  EXCEPTIONS
    INVALID_LENGTH = 1
    NO_MEMORY = 2
    INTERNAL_ERROR = 3.

  do i1 TIMES.
    CONCATENATE 'FF' pkcs_ff_s INTO pkcs_ff_s.
  enddo.
  pkcs_ff_x = pkcs_ff_s.

REPLACE ALL OCCURRENCES OF pkcs_zero in pkcs_rnd with pkcs_one IN BYTE MODE.

CONCATENATE
 pkcs_head_encr
 pkcs_rnd
 pkcs_zero
 msg_xstr
into msg_xstr_e in byte mode.

write: / 'Plain message PKCS1-V1.5 padded for encryption in HEX:'.
PERFORM SHOW_DATA USING msg_xstr_e.
SKIP.

" Convert the padded plain text message from HEX to DEC
i1 = xstrlen( msg_xstr_e ).
bi2->seti( 1 ).
WHILE ( i1 > 0 ).
  i1 = i1 - 1.
  i2 = msg_xstr_e+i1(1).
  bi1->seti( i2 ).
  bi1->mul( bi2 ).
  bi2->mul( bi256 ).
  msg_plain_bi = msg_plain_bi->add( bi1 ).
ENDWHILE.

" Encrypt the message
GET RUN TIME FIELD T1.
msg_encr_bi = msg_plain_bi->powmod( x = publicExponent
                                    m = pub_modulus_bi ).
GET RUN TIME FIELD T2.
T3 = T2 - T1.
write: / 'Encryption time:', T3.

" Convert the encrypted message from DEC to HEX
WHILE ( s <> '0' ).
  i1 = bi2->setobj( msg_encr_bi )->mod( bi256 )->getstr( 0 ) + i3.
  if i1 = 256.
     i3 = 1.
  else.
     i3 = 0.
  endif.
  x1 = i1.
  s = msg_encr_bi->div( bi256 )->getstr( 0 ).
  CONCATENATE x1 msg_encr_x INTO msg_encr_x IN BYTE MODE.
ENDWHILE.

" output encrypted message
OPEN DATASET msg_file_name FOR OUTPUT IN BINARY MODE.
TRANSFER msg_encr_x TO msg_file_name.
CLOSE DATASET msg_file_name.

write: / 'RSA encrypted message:'.
PERFORM SHOW_DATA USING msg_encr_x.
SKIP.

*---------------------
* END ENCRYPTION
*---------------------


*---------------------
* START SIGNING
*---------------------
" Message PKCS#1 padding for signing
CONCATENATE
 pkcs_head_sign
 pkcs_ff_x
 pkcs_zero
 msg_xstr
into msg_xstr_s in byte mode.
write: / 'Plain message PKCS1-V1.5 padded for signing in HEX:'.
PERFORM SHOW_DATA USING msg_xstr_s.
SKIP.

" Convert the padded plain text message from HEX to DEC
msg_plain_bi->seti( 0 ).
i1 = xstrlen( msg_xstr_s ).
bi2->seti( 1 ).
WHILE ( i1 > 0 ).
  i1 = i1 - 1.
  i2 = msg_xstr_s+i1(1).
  bi1->seti( i2 ).
  bi1->mul( bi2 ).
  bi2->mul( bi256 ).
  msg_plain_bi = msg_plain_bi->add( bi1 ).
ENDWHILE.

" Sign the message
GET RUN TIME FIELD T1.
msg_encr_bi = msg_plain_bi->powmod( x = priv_exponent_bi
                                    m = pub_modulus_bi ).
GET RUN TIME FIELD T2.
i1 = T2 - T1.
write: / 'Signing time:', i1.

s = ''.
msg_sign_x = ''.

" Convert the encrypted message from DEC to HEX
WHILE ( s <> '0' ).
  i1 = bi2->setobj( msg_encr_bi )->mod( bi256 )->getstr( 0 ) + i3.
  if i1 = 256.
     i3 = 1.
  else.
     i3 = 0.
  endif.
  x1 = i1.
  s = msg_encr_bi->div( bi256 )->getstr( 0 ).
  CONCATENATE x1 msg_sign_x INTO msg_sign_x IN BYTE MODE.
ENDWHILE.

" Output signed message
OPEN DATASET msg_file_name_s FOR OUTPUT IN BINARY MODE.
TRANSFER msg_sign_x TO msg_file_name_s.
CLOSE DATASET msg_file_name_s.

write: / 'RSA signed message:'.
PERFORM SHOW_DATA USING msg_sign_x.

*---------------------
* END SIGNING
*---------------------

FORM SHOW_DATA USING  data_x TYPE xstring.
  DATA: data_len TYPE I
      , i1       TYPE I value 0
      , i2       TYPE I value 32.
  data_len = xstrlen( data_x ).
  WHILE ( i1 < data_len ).
    i2 = nmin( val1 = i2
               val2 = data_len ).
    WRITE: / data_x+i1(i2).
    i1 = i1 + 32.
  ENDWHILE.
ENDFORM.

mkdir -p /tmp/rsa
cd /tmp/rsa

openssl genrsa -out /tmp/rsa/rsa.key 2048
openssl pkey -in /tmp/rsa/rsa.key -text

xxd /tmp/rsa/encrypted_msg
openssl /tmp/rsa/rsautl -decrypt -in /tmp/rsa/encrypted_msg -inkey /tmp/rsa/rsa.key | xxd
openssl /tmp/rsa/rsautl -decrypt -in /tmp/rsa/encrypted_msg -inkey /tmp/rsa/rsa.key -raw | xxd

xxd /tmp/rsa/signed_msg
openssl /tmp/rsa/rsautl -verify -in /tmp/rsa/signed_msg -inkey /tmp/rsa/rsa.key | xxd
openssl /tmp/rsa/rsautl -verify -in /tmp/rsa/signed_msg -inkey /tmp/rsa/rsa.key -raw | xxd

RSA Encryption in ABAP | SAP Blogsicon-default.png?t=M3K6https://blogs.sap.com/2021/04/13/rsa-encryption-in-abap/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SAP爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值