主頁 > 企業開發 > ABAP RSA 加密

ABAP RSA 加密

2021-08-31 22:30:02 企業開發

最近出現一些SAP ABAP RSA加密的需求,這里搬運一篇文章,用于學習參考,

 

本文鏈接:https://www.cnblogs.com/hhelibeb/p/14952732.html

原文標題:RSA Encryption in ABAP

 

最近我偶然在SAP社區發現了很多關于RSA加密的未解答的問題,在這里我將嘗試提供一些例子,說明如何在ABAP中使用公鑰/私鑰加密,

所有的間接問題,如證書、信任、撤銷和密鑰生成,在本文中不會涉及,密鑰將用openssl生成,

例子1 – 用自己的ABAP RSA實作

RSA加密是非常簡單的,只需要整數算術--主要是模冪運算,唯一的問題是,所涉及的整數比ABAP和大多數其他語言默認能處理的長,幸運的是,這個問題被Harry Boeck用Z04_BIGINTX類解決了,可以在這里找到(出色的作業),

備注:評論區提到另一個解決方案abapPGP,

生成RSA key

創建一個作業目錄,并進入,

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

生成2048位RSA密鑰,

/tmp/rsa > openssl genrsa -out rsa.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.....................................................................+++++
.......+++++
e is 65537 (0x010001)

用純文本輸出公鑰和私鑰,我們只需要模數(modulus)、公鑰指數(publicExponent)和私鑰指數(privateExponent),

/tmp/rsa > openssl pkey -in rsa.key -text
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDiBbntt4wk807Q
Bzh0gdwwXFyxe1/a41dDZeekgxC5p649B1pT6Ft7P6eSmZqDdZ6t04JpzAdyHjzj
2DMPt6VpAkXyaQSXLHd7dKWYnw2b/akWptd761zx9oIY1tHz0y4VbfkX0yt7FwvP
jUK6XfpcyYymJ1KMmG/UhsIENLxhaU56/gnKdl01XTcKe+JkBpv02dpw+bw6BE34
21FXFmSpoduAHA8/lm+9U6PqdvxU6IDB16n5X74IyUCTQsMW7XQgaw3cqVWTYigU
sZFbHPEddfkCZDNfSodmRd+WZTuCRjD6+K/9+K1j7Kk4a2LMC7r0bPOIYcrW+0VC
+ykiz8QTAgMBAAECggEBAL27/tt+FEhEcymQliS/in6SWkGnBs1xwKRUXEMuvxCK
oWqbzIjZakopIlufVCT8zMqw3i4/1xRGK+k8aYjNKi7feKZI4FCjRF2/iu92vW7w
XkwknIlrB6gavhVp5+9dnLbijZMhcsOukfyWYaifEXdovggQxGw/3siyoxXyyxyd
PSB1Wf+LdZ1EOTaEfk3+lgEpEUzdFTNEC/jwrQJiXzSB+nP5bB0Az3kMcbhxwa01
hAUylXCNtnrRJv0sMvQJOy59gBjiPn3GW62t8Kf/km3IlDRKE7h9xYECafQabaXR
0q6swX09YpdKKBEHYLE9ArpamJtJYPtlA2XSvsfBqkECgYEA84Bt20EpBPldrUFN
GLb7qKNPawRbMff204xx7OtzHD77Th6hcvaXU0C/D4c+DMZNQ/2M4xbLoZWPTOnK
BxOhpbZMH4prxLA4U/6TDQwo9F3kW/1zPcYKfxOgW6tlVHWnLR4Kd1+W7ygNOhjV
El6lWwi008547z05w5ZQ2T+U3OECgYEA7Z+fO6ZWIRqHJq1MCzStTtS+hGkwJArj
DGy8AbvGV7LScmH31sxRJqZp6jHMOICBjgwAPN0VE5eq+xUcPs0p5/seTy/MzSbf
uRG+A//PIG/yUVuOV6nuCYKsY2v2oTUF+v8HGMkfa7WkEhD5S5lZ+oA8gVMXQ4Ey
J235xfPu63MCgYEA4qA+HljX14RK1kw3d/Ad6ocMDDsCsU/qDlvhUDKWcMyBUeSa
OIgesOJKsCYb7wHEuanKrTPzE5FBzMCuQcXYpYUz9gr7YBTuZ+ZAcF1H5J9aQO9z
iSO/cyQOFCNB7MiPbiNOdGmn7S/ml5KzBCTIWyCQQ60fyvG9yDYnSvqtDqECgYBk
29Cxd9us916QKxRQ2U4KXMB04VTep4RRnMF8FuCMDsnGZRDWKijzt8TS88oT3W+g
BDYBn3E3vLOFGSPBAEIeRfdKcyaBmVNycTZu6iBXS0zV/X+AdA8mGEHlfUjUifX8
4Ex517wvcoyuYmf+D5wieFW2KreAHpFULRjMTcqGQwKBgQCMrLoC1dasdvcQ/d9r
sd1AlGjSjoVhGeb19NYQMdOxx29vExP45ClSmnTCTZIZFVpeXHQ4X3ALq2uK4bQp
Cyqrz+4TRLY9e9qgTqNsWkhyke9YSAYNxCb17ZXf7rtHgTJeGbnDvrKC8xa2EvgR
sZknhXCegj6UBsECwPBrYZoDag==
-----END PRIVATE KEY-----
RSA Private-Key: (2048 bit, 2 primes)
modulus:
    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
publicExponent: 65537 (0x10001)
privateExponent:
    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
.
.
.
key

現在有了key和類Z04_BIGINTX,我們可以寫程式了,

ABAP程式

在下面的程式中,我們用公鑰加密,用私鑰簽署"Thirty-two bytes secret message!"這個資訊,結果顯示在螢屏上,它們被保存在生成密鑰的相同檔案夾中,

簽名通常包括對訊息進行散列(hash),并對散列值進行簽名,但是因為我們的訊息足夠小,我們跳過散列步驟,直接對訊息本身進行簽名,作為概念證明,這樣做應該是足夠的,
實際的作業只是幾行代碼而已,


加密:

msg_encr_bi = msg_plain_bi->powmod( x = publicExponent
                                    m = pub_modulus_bi ).

簽名:

msg_encr_bi = msg_plain_bi->powmod( x = priv_exponent_bi
                                    m = pub_modulus_bi ).

剩下的就是將十六進制轉換為十進制,然后再轉換回來,

 

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.

 輸出如下,

 我們看到用公鑰指數加密,幾乎總是65537,需要約0.2秒,而用私鑰指數簽名需要30秒,

現在讓我們用openssl檢查一下結果,

解密,

/tmp/rsa >xxd encrypted_msg
00000000: dd64 ff4c f19e 6274 b3fd aa8b ecc2 9fe0  .d.L..bt........
00000010: 6d87 760f 1239 d01f 81ce e53b 3587 f601  m.v..9.....;5...
00000020: 8e03 4099 a582 bbdd e45b 7cf7 be79 76b9  ..@......[|..yv.
00000030: 7068 3cd5 2b72 a7d6 2c51 e805 36d3 3eb8  ph<.+r..,Q..6.>.
00000040: c11c 4584 01f3 3bfd d265 1bf7 aff1 d97a  ..E...;..e.....z
00000050: aded 0b4a b59d 3c3c 4675 e38d 8409 aedc  ...J..<<Fu......
00000060: 1242 b562 5ced 9662 c9f3 5974 4cc3 3227  .B.b\..b..YtL.2'
00000070: b750 6cea e244 892b 873f 32e7 c4fd 4f78  .Pl..D.+.?2...Ox
00000080: 6a5e 7063 d0fe c5ef 9219 8549 b025 47c9  j^pc.......I.%G.
00000090: 0b3a 5598 d780 aab4 ab5a 6bb0 8ba5 f822  .:U......Zk...."
000000a0: 735f 2b43 68e6 5630 9c90 1712 6196 6d06  s_+Ch.V0....a.m.
000000b0: e2fc 87c1 db42 554f 3688 929a 6550 5173  .....BUO6...ePQs
000000c0: b951 30f6 ca5b a60a 2cc7 5710 915a 2809  .Q0..[..,.W..Z(.
000000d0: c6d8 60ba 3eac bcc1 9814 cc6a e777 757f  ..`.>......j.wu.
000000e0: 44ae ce00 3869 a275 4c4b 3f8e e5e2 eb67  D...8i.uLK?....g
000000f0: 34ac 13cb f89e 5edc 9d67 d5e8 704e d9c6  4.....^..g..pN..
/tmp/rsa >
/tmp/rsa >openssl rsautl -decrypt -in encrypted_msg -inkey rsa.key | xxd
00000000: 5468 6972 7479 2d74 776f 2062 7974 6573  Thirty-two bytes
00000010: 2073 6563 7265 7420 6d65 7373 6167 6521   secret message!
Decrypt

添加raw引數,讓openssl顯示完整訊息,

/tmp/rsa >openssl rsautl -decrypt -in encrypted_msg -inkey rsa.key -raw | xxd
00000000: 0002 4316 8cf2 e289 8dc4 67cf be1b f547  ..C.......g....G
00000010: ae0b b98b 8ef8 79ba 9b98 ac20 3660 d6ac  ......y.... 6`..
00000020: 3330 e613 752c a9ab 3f88 368b 223b 050b  30..u,..?.6.";..
00000030: b79d 40c2 2ef9 9de9 e363 10d1 199b 97f0  [email protected]......
00000040: 33da b96d e3fc 62d6 06c4 ebb5 3ee2 b823  3..m..b.....>..#
00000050: 4f22 d924 ac1d dd89 0215 889f 4c1f 9364  O".$........L..d
00000060: 1220 81bd 21d7 1dd2 280e d74a 4024 99ae  . ..!...(..J@$..
00000070: a8ed 3fad 30aa e281 db4c 5454 c237 9bc0  ..?.0....LTT.7..
00000080: 9338 2a39 197b 9972 4c11 b260 7f31 e407  .8*9.{.rL..`.1..
00000090: 81ea 2be7 a9da 336b 6b66 8bde 1774 3bd0  ..+...3kkf...t;.
000000a0: 0ccd 3b93 983c 1c51 b32d a31b 06f6 533e  ..;..<.Q.-....S>
000000b0: 144a 1c2a f32d 875f 4873 8b41 dcc7 8b18  .J.*.-._Hs.A....
000000c0: 40e4 4414 bd7e c49a 5282 b165 3698 fdf6  @.D..~..R..e6...
000000d0: 9e20 b83b 3185 c7ee 962a 9bb5 f173 8900  . .;1....*...s..
000000e0: 5468 6972 7479 2d74 776f 2062 7974 6573  Thirty-two bytes
000000f0: 2073 6563 7265 7420 6d65 7373 6167 6521   secret message!
View Code

驗證,

/tmp/rsa >xxd signed_msg
00000000: d540 f2b5 1e7e bb83 aa6e d099 1ad6 ee1e  .@...~...n......
00000010: ccdb ffaf e579 0e98 323e b055 7164 4b71  .....y..2>.UqdKq
00000020: a71c 0e6e 5e74 3fdb c914 97ac e063 8ece  ...n^t?......c..
00000030: 086e d8ac fad9 14a7 7f47 bd34 22a9 d0ab  .n.......G.4"...
00000040: 73e7 80fc 65af fbd7 d3df 7672 1d31 88e7  s...e.....vr.1..
00000050: b489 311c eb36 25bf 3e8b 4efb b97c df96  ..1..6%.>.N..|..
00000060: 5440 165b a820 514d 9649 531f 402c 5767  T@.[. QM.IS.@,Wg
00000070: 508c adeb 1954 e14f e2ce d64e ba30 0c4a  P....T.O...N.0.J
00000080: aeca 0927 7823 9bc6 0083 99f7 e605 ae9d  ...'x#..........
00000090: 2cd9 205e 41f4 1587 5b3f 1574 047d 42b3  ,. ^A...[?.t.}B.
000000a0: 6e5a a74b cfaa fde5 4d09 26f9 82ca f1b5  nZ.K....M.&.....
000000b0: 9299 f2df 7444 472d 1554 3378 c544 7f20  ....tDG-.T3x.D.
000000c0: b6b0 80be a241 2d24 c561 da69 522d 86db  .....A-$.a.iR-..
000000d0: 2388 cbe5 15fe 9967 3bbd 36f5 5a70 8a05  #......g;.6.Zp..
000000e0: a30c 2c89 2f05 b470 15d3 482f e53b 947a  ..,./..p..H/.;.z
000000f0: c7f5 feba bd41 a877 750e c9f8 cb7a c7b1  .....A.wu....z..
/tmp/rsa >
/tmp/rsa >openssl rsautl -verify -in signed_msg -inkey rsa.key | xxd
00000000: 5468 6972 7479 2d74 776f 2062 7974 6573  Thirty-two bytes
00000010: 2073 6563 7265 7420 6d65 7373 6167 6521   secret message!
/tmp/rsa >
/tmp/rsa >openssl rsautl -verify -in signed_msg -inkey rsa.key -raw | xxd
00000000: 0001 ffff ffff ffff ffff ffff ffff ffff  ................
00000010: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000020: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000030: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000040: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000050: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000060: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000070: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000080: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000090: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000a0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000b0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000c0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000d0: ffff ffff ffff ffff ffff ffff ffff ff00  ................
000000e0: 5468 6972 7479 2d74 776f 2062 7974 6573  Thirty-two bytes
000000f0: 2073 6563 7265 7420 6d65 7373 6167 6521   secret message!
Verify

例子2 – 使用CommonCryptoLib

所有RSA的東西都可以用函陣列SSFW - SSF Function for Web Services Security輕松完成,除了你可以用openssl中的(-raw)開關得到的東西外,其他的都可以,例如,如果你想使用非標準的padding,這應該是很少見的情況,


為了方便,我將從例1中使用的密鑰創建一個PSE并使用該PSE,
在生產中,你可以考慮通過SSFA、STRUST和SSF_GET_PARAMETER來進行,

 

創建PSE,

/tmp/rsa > openssl req -x509 -sha256 -key rsa.key -out user1.cer -days 3650 -subj '/CN=user1'
/tmp/rsa > openssl pkcs12 -export -inkey rsa.key -in user1.cer -out user1.pfx -nodes
Enter Export Password:
Verifying - Enter Export Password:
/tmp/rsa > setenv SECUDIR $PWD
/tmp/rsa > sapgenpse import_p12 -x "" -p user1.pse user1.pfx
Found key 'INDEX=0,SIG=YES,ENC=YES,MD5-FINGERPRINT=3B9E 77DD E5E4 3371 19FA 2FCF D1CA 512F,KEYID=3D1E2BC7E33500A3D2A098B63FE9962A6B63318C'

!!! WARNING: For security reasons it is recommended to use a PIN/passphrase
!!! WARNING: which is at least 8 characters long and contains characters in
!!! WARNING: upper and lower case, numbers and non-alphanumeric symbols.

PSE "/tmp/rsa/user1.pse" was written

ABAP程式,

REPORT Z_RSA_CCL.

DATA: lf_output        TYPE xstring.
DATA: lf_plain_input_x TYPE xstring.
DATA: lf_plain_input   TYPE string.
DATA: msg_file_name    TYPE STRING.

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


lf_plain_input = 'Thirty-two bytes secret message.'.
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
  EXPORTING
      text = lf_plain_input
  IMPORTING
    buffer = lf_plain_input_x.

DATA: it_recipient_list   TYPE STANDARD TABLE OF ssfinfo,
      wa_recipient_list   LIKE LINE OF it_recipient_list.
wa_recipient_list-id = 'CN=user1'.
APPEND wa_recipient_list TO it_recipient_list.

GET RUN TIME FIELD T1.
CALL FUNCTION 'SSFW_KRN_ENVELOPE'
  EXPORTING
    STR_FORMAT       = 'PKCS1-V1.5'
    STR_PAB          = '/tmp/rsa/user1.pse'
    ostr_input_data  = lf_plain_input_x
  IMPORTING
     OSTR_ENVELOPED_DATA = lf_output
  TABLES
      RECIPIENT_LIST = it_recipient_list
  EXCEPTIONS
      OTHERS = 1.
GET RUN TIME FIELD T2.
T3 = T2 - T1.
write: / 'Encryption time:', T3.

msg_file_name = '/tmp/rsa/ccl_encrypted_msg'.
OPEN DATASET msg_file_name FOR OUTPUT IN BINARY MODE.
TRANSFER lf_output TO msg_file_name.
CLOSE DATASET msg_file_name.

write: / 'RSA CCL encrypted message:'.
PERFORM SHOW_DATA USING lf_output.
skip.

DATA: lf_signer          TYPE ssfinfo.
DATA: lt_signer TYPE STANDARD TABLE OF ssfinfo." WITH HEADER LINE.
lf_signer-id = 'CN=user1'.
lf_signer-profile = '/tmp/rsa/user1.pse'.
APPEND lf_signer TO lt_signer.

GET RUN TIME FIELD T1.
CALL FUNCTION 'SSFW_KRN_SIGN'
  EXPORTING
    str_format       = 'PKCS1-V1.5'
    str_chainfmt     = 'X509v3'
    STR_HASHALG      = 'SHA256'
    ostr_input_data  = lf_plain_input_x
  IMPORTING
    ostr_signed_data = lf_output
  TABLES
    signer           = lt_signer
  EXCEPTIONS
    OTHERS =              1.
GET RUN TIME FIELD T2.
T3 = T2 - T1.
write: / 'Signing time:', T3.


msg_file_name = '/tmp/rsa/ccl_signed_msg'.
OPEN DATASET msg_file_name FOR OUTPUT IN BINARY MODE.
TRANSFER lf_output TO msg_file_name.
CLOSE DATASET msg_file_name.

write: / 'RSA CCL signed message:'.
PERFORM SHOW_DATA USING lf_output.


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.

 

運行后,

 

 

解密,

/tmp/rsa > xxd ccl_encrypted_msg
00000000: 3c5b 4c97 0c5c 0e68 1f84 7ced 4f01 e11c  <[L..\.h..|.O...
00000010: 3bce b761 a03e ad15 2f9d 5836 f187 1e44  ;..a.>../.X6...D
00000020: ca71 7cfb 84ef 0b2d 2203 fe6a 502e f065  .q|....-"..jP..e
00000030: 9790 c4cd 8164 912b 8b13 926b 4537 b953  .....d.+...kE7.S
00000040: a3d1 1f15 0919 ccf4 d3af 9e2b 6bfb 7e61  ...........+k.~a
00000050: 1f25 6d70 c9d5 c48e b38b aa6c 5300 d22b  .%mp.......lS..+
00000060: aaac e4b5 6dc5 cb66 39a2 86e2 a41d 96ab  ....m..f9.......
00000070: 6901 ade9 8a17 74df 8237 a963 73a4 4da9  i.....t..7.cs.M.
00000080: bf13 7be2 704a fc8c 8889 1fad 279e 6397  ..{.pJ......'.c.
00000090: 2d13 d0d1 22a2 c0de 8c72 b12f bd90 31ec  -..."....r./..1.
000000a0: ef98 0a7f f971 5f71 4a9f 4060 0715 4c40  .....q_qJ.@`..L@
000000b0: 1397 09c8 333b df8a 3243 2db3 c276 d875  ....3;..2C-..v.u
000000c0: 6cad 5dcb af41 f00c 2cad 4053 da72 158c  l.]..A..,[email protected]..
000000d0: ac67 52ad 6940 8049 4c3c 727a a19e a513  [email protected]<rz....
000000e0: 716d a4eb 0826 07c4 1624 307f 68d6 3014  qm...&...$0.h.0.
000000f0: 43ec 2cb8 ea44 2868 1a24 e1aa 594b e646  C.,..D(h.$..YK.F

/tmp/rsa > openssl rsautl -decrypt -in ccl_encrypted_msg -inkey rsa.key | xxd
00000000: 5468 6972 7479 2d74 776f 2062 7974 6573  Thirty-two bytes
00000010: 2073 6563 7265 7420 6d65 7373 6167 652e   secret message.

/tmp/rsa > openssl rsautl -decrypt -in ccl_encrypted_msg -inkey rsa.key -raw | xxd
00000000: 0002 da46 9aee 3bb8 53e7 9ecf 99a0 0a60  ...F..;.S......`
00000010: e8cc 89e5 56ad 4c10 d2a5 6a62 6612 068e  ....V.L...jbf...
00000020: 9f7a e956 4325 0b32 7e75 457a ac75 639c  .z.VC%.2~uEz.uc.
00000030: 64a5 17b7 5c1c 721a d2d3 1a2b 1770 0a73  d...\.r....+.p.s
00000040: ccec 5802 66b7 d2e3 2f96 11bd 6708 2d3d  ..X.f.../...g.-=
00000050: 298c 76ce 02f9 7b84 4a36 911b 81ad d047  ).v...{.J6.....G
00000060: 5452 6e64 2d0d f55a c048 9f13 2aef ff70  TRnd-..Z.H..*..p
00000070: ff2d 7c5d 0162 a8d0 82d2 5c64 bf3c e380  .-|].b....\d.<..
00000080: b93d 4d98 a1b6 164c 8ded 016d ad94 9fd2  .=M....L...m....
00000090: 7632 e64c 080f 7728 5817 0f50 1d9c cfd3  v2.L..w(X..P....
000000a0: f67e 5ccb eafb 9cc9 9916 4bd4 c64e 1494  .~\.......K..N..
000000b0: f47f e38e 33f4 2121 91df d9f9 7233 f182  ....3.!!....r3..
000000c0: 2008 bb21 654d 0fd3 482d da42 8cfb b4c1   ..!eM..H-.B....
000000d0: a267 78ae e55e cde5 1f8d e3e6 d5df 1000  .gx..^..........
000000e0: 5468 6972 7479 2d74 776f 2062 7974 6573  Thirty-two bytes
000000f0: 2073 6563 7265 7420 6d65 7373 6167 652e   secret message.
Decrypt

驗證,

/tmp/rsa > xxd ccl_signed_msg
00000000: 9e8f 2678 2ed6 3d6d ae74 16f6 4101 75ed  ..&x..=m.t..A.u.
00000010: 3fd0 d962 7f2b 7d46 f3b7 8097 7411 37f3  ?..b.+}F....t.7.
00000020: 89c6 e3fc 81b7 93a6 7814 020b 9b3a 8ebd  ........x....:..
00000030: 9e9f 3549 e521 a7ff 27ef aef5 10f5 dada  ..5I.!..'.......
00000040: e2cb f6b9 8cf4 c663 43f2 98d7 2127 040d  .......cC...!'..
00000050: 6b4e 7c23 bad7 db40 7442 9c4d d6b4 b0f9  kN|#[email protected]....
00000060: 2e35 5500 1499 c938 536f 6763 99b5 895b  .5U....8Sogc...[
00000070: 2b57 5b81 f757 ffee f7fa dc8c b447 afd8  +W[..W.......G..
00000080: 1630 ac6f 5621 8fc1 c3ab ed7f 1893 3b91  .0.oV!........;.
00000090: 9575 055c 7a9e 6a76 b5ce 000e 5ab2 3eae  .u.\z.jv....Z.>.
000000a0: 5574 2a8e f0fa 3f2e 9897 2c95 4e64 16bc  Ut*...?...,.Nd..
000000b0: 0040 00fd 3202 d458 8c1f 45da 7f1c f238  [email protected]
000000c0: 8e68 0dc1 b692 d1bb 48c2 2f0d a429 eaa8  .h......H./..)..
000000d0: b962 05ba 0a7b b246 7719 1406 5649 0681  .b...{.Fw...VI..
000000e0: fae5 dadd 7946 1775 5e2d eff7 2d95 993a  ....yF.u^-..-..:
000000f0: 9a6f 4e7b 0770 b887 b34f 271a 43af 8e68  .oN{.p...O'.C..h

/tmp/rsa > openssl rsautl -verify -in ccl_signed_msg -inkey rsa.key | xxd
00000000: 3031 300d 0609 6086 4801 6503 0402 0105  010...`.H.e.....
00000010: 0004 20c0 4726 d78a 7628 27e3 dffe 9f42  .. .G&..v('....B
00000020: c2fe e624 7a2e 59f7 a0c9 85ef 7728 a5d4  ...$z.Y.....w(..
00000030: a106 8f                                  ...

/tmp/rsa > openssl rsautl -verify -in ccl_signed_msg -inkey rsa.key -raw | xxd
00000000: 0001 ffff ffff ffff ffff ffff ffff ffff  ................
00000010: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000020: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000030: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000040: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000050: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000060: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000070: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000080: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000090: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000a0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000b0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000c0: ffff ffff ffff ffff ffff ffff 0030 3130  .............010
000000d0: 0d06 0960 8648 0165 0304 0201 0500 0420  ...`.H.e.......
000000e0: c047 26d7 8a76 2827 e3df fe9f 42c2 fee6  .G&..v('....B...
000000f0: 247a 2e59 f7a0 c985 ef77 28a5 d4a1 068f  $z.Y.....w(.....

/tmp/rsa > echo -n 'Thirty-two bytes secret message.' | sha256sum
c04726d78a762827e3dffe9f42c2fee6247a2e59f7a0c985ef7728a5d4a1068f  -
Verify

 

這里我們看到訊息的SHA散列值被簽名了,

總結

在這里我們學習了如何在ABAP中使用2種不同的方法對短資訊進行RSA加密/簽名,

    1,純粹的ABAP實作,它在性能(和安全性)上遠遠比不上CommonCryptoLib,它的意義在于,讓我們更好地了解什么是RSA加密,
    2,CommonCryptoLib,這里的例子是一個基本的例子,還有很多東西可以做,可能會在下一篇博客中介紹,

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/296341.html

標籤:SAP

上一篇:【odoo14】【開發側】權限配置

下一篇:ABAP RSA 加密

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more