SAP ABAP DES加密实现

2023-10-13 19:08:21 浏览数 (1)

一、标准方法(cl_sec_sxml_writer)实现

        标准方法中DES加密模式为CBC,填充为pkcs7padding

  • DES对称加密加密示例
代码语言:javascript复制
DATA: lv_base64 TYPE string,
      lv_str    TYPE string.

DATA: lv_data      TYPE string,
      lv_data_xstr TYPE xstring,
      lv_key_xstr  TYPE xstring,
      lv_key_str   TYPE string,
      lv_iv_xstr   TYPE xstring,
      lv_iv_str    TYPE string,
      lv_en_xstr   TYPE xstring,
      lv_de_xstr   TYPE xstring,
      lv_de_str    TYPE string,
      lv_en_str    TYPE string.


lv_data = '待加密字符串'.
lv_data_xstr = cl_bcs_convert=>string_to_xstring( iv_string   = lv_data iv_codepage = '4110' ).

" DES key 8字节,如果为Triple DES加密(3DES)key为24字节,转化为十六进制使用
lv_key_str = 'ABCDEFGH'.
lv_key_xstr = cl_bcs_convert=>string_to_xstring( iv_string   = lv_key_str iv_codepage = '4110' ).

" 偏移量 cbc模式使用
lv_iv_str = '12345678'.
lv_iv_xstr = cl_bcs_convert=>string_to_xstring( iv_string   = lv_iv_str iv_codepage = '4110' ).

TRY.
    cl_sec_sxml_writer=>encrypt_iv(
      EXPORTING
        plaintext =  lv_data_xstr
        key       =  lv_key_xstr
        iv        =  lv_iv_xstr
        algorithm =  cl_sec_sxml_writer=>co_tdes_algorithm
      IMPORTING
        ciphertext = lv_en_xstr ).
  CATCH cx_root.
ENDTRY.

" 移除偏移量
lv_en_str =  lv_en_xstr.
IF strlen( lv_en_str ) > 16.
  SHIFT lv_en_str LEFT BY 16 PLACES.
  lv_en_xstr = lv_en_str.
ENDIF.

CALL FUNCTION 'SCMS_BASE64_ENCODE_STR'
  EXPORTING
    input  = lv_en_xstr
  IMPORTING
    output = lv_str.

WRITE:/ lv_str.
  • DES对称加密解密示例
代码语言:javascript复制
DATA: lv_base64 TYPE string,
      lv_str    TYPE string.

DATA: lv_data      TYPE string,
      lv_data_xstr TYPE xstring,
      lv_key_xstr  TYPE xstring,
      lv_key_str   TYPE string,
      lv_iv_xstr   TYPE xstring,
      lv_iv_str    TYPE string,
      lv_en_xstr   TYPE xstring,
      lv_de_xstr   TYPE xstring,
      lv_de_str    TYPE string,
      lv_en_str    TYPE string.

lv_base64 = 'ZEhhKTgGh80ZoQ9stHqNsh4oQeJKTBxy'.
CALL FUNCTION 'SCMS_BASE64_DECODE_STR'
  EXPORTING
    input  = lv_base64
*   UNESCAPE       = 'X'
  IMPORTING
    output = lv_en_xstr
  EXCEPTIONS
    failed = 1
    OTHERS = 2.

" 前置8位补位 偏移量
lv_iv_str = '12345678'.
lv_iv_xstr = cl_bcs_convert=>string_to_xstring( iv_string   = lv_iv_str iv_codepage = '4110' ).
lv_en_xstr = lv_iv_xstr && lv_en_xstr.

" DES key 8字节,如果为Triple DES加密(3DES)key为24字节,转化为十六进制使用
lv_key_str = 'ABCDEFGH'.
lv_key_xstr = cl_bcs_convert=>string_to_xstring( iv_string   = lv_key_str iv_codepage = '4110' ).

TRY.
    cl_sec_sxml_writer=>decrypt(
      EXPORTING
        ciphertext = lv_en_xstr
        key        = lv_key_xstr
         algorithm  = cl_sec_sxml_writer=>co_tdes_algorithm
       IMPORTING
         plaintext  = lv_de_xstr
           ).
  CATCH cx_root.
ENDTRY.

lv_de_str = cl_bcs_convert=>xstring_to_string( iv_xstr = lv_de_xstr iv_cp = '4110' ).

WRITE: / '解密后字符串:', lv_de_str.
  • 3DES加密(Triple DES)

        3DES加密使用三组DES密钥进行DES加密操作;过程中首先使用第一组8字节密钥对明文进行加密操作,然后使用第二组密钥对上一步加密结果进行解密操作,最后使用第三组密钥再对上一步解密结果进行加密操作。如果三组密钥相同或密钥长度仅为8字节,则3DES加密和DES加密一致。上述DES加密示例中调用的方法实际为Triple DES加密,因此只需要将密钥长度改为24位即为3DES加密。

  • 参考

        填充模式

        zeropadding 最后不足8字节部分,填充0

        pkcs5padding 最后不足8字节部分,少n位,填充该n个n值

        pkcs7padding  和pkcs5padding类似,只是字节数为1-255,而不是8

        DES加密模式,填充方式介绍:DES加密原理和作用是什么-电子发烧友网

二、openssl命令行实现

  • 实现示例
代码语言:javascript复制
DATA: lv_output TYPE xstring,
      lv_input  TYPE string.

DATA: lv_base64   TYPE string,
      lv_key_xstr TYPE xstring,
      lv_key_str  TYPE string,
      lv_iv_xstr  TYPE xstring,
      lv_iv_str   TYPE string.

DATA: lv_inputfile  TYPE string,
      lv_outputfile TYPE string.

DATA:lv_parameters    TYPE sxpgcolist-parameters,
     lv_status        TYPE extcmdexex-status,
     lv_exitcode      TYPE extcmdexex-exitcode,
     lt_exec_protocol  TYPE TABLE OF btcxpm.

DATA: timestamp TYPE timestampl,
      str       TYPE string.

GET TIME STAMP FIELD timestamp.
str = timestamp.
REPLACE ALL OCCURRENCES OF '.' IN str WITH ''.
CONDENSE str NO-GAPS.
lv_inputfile  = '/tmp/temp_input'   && '.txt'.
lv_outputfile = '/tmp/temp_output'  && '.txt'.

lv_input = '待加密字符串'.

" 写入 明文
OPEN DATASET lv_inputfile FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
TRANSFER lv_input TO lv_inputfile.
CLOSE DATASET lv_inputfile.

"  偏移量
lv_iv_str = '12345678'.
lv_iv_str = cl_bcs_convert=>string_to_xstring( iv_string   = lv_iv_str iv_codepage = '4110' ).
lv_iv_str = to_lower( lv_iv_str ).


" DES key
lv_key_str = 'ABCDEFGH'.
lv_key_str = cl_bcs_convert=>string_to_xstring( iv_string   = lv_key_str iv_codepage = '4110' ).
lv_key_str = to_lower( lv_key_str ).

lv_parameters = |enc -e -des-cbc -in { lv_inputfile } -out { lv_outputfile } -K { lv_key_str } -iv { lv_iv_str }|.
"lv_parameters = |enc -d -des-cbc -in { lv_inputfile } -out { lv_outputfile } -K { lv_key_str } -iv { lv_iv_str }|. 解密

CALL FUNCTION 'SXPG_COMMAND_EXECUTE'
  EXPORTING
    commandname                   = 'ZRSA'
    additional_parameters         = lv_parameters
    operatingsystem               = sy-opsys
  IMPORTING
    status                        = lv_status
    exitcode                      = lv_exitcode
  TABLES
    exec_protocol                 = lt_exec_protocol
  EXCEPTIONS
    no_permission                 = 1
    command_not_found             = 2
    parameters_too_long           = 3
    security_risk                 = 4
    wrong_check_call_interface    = 5
    program_start_error           = 6
    program_termination_error     = 7
    x_error                       = 8
    parameter_expected            = 9
    too_many_parameters           = 10
    illegal_command               = 11
    wrong_asynchronous_parameters = 12
    cant_enq_tbtco_entry          = 13
    jobcount_generation_error     = 14
    OTHERS                        = 15.

" 读取加密后文件
IF sy-subrc = 0 AND lv_status <> 'E'.
  OPEN DATASET lv_outputfile FOR INPUT IN BINARY MODE.
  READ DATASET lv_outputfile INTO lv_output.
  CLOSE DATASET lv_outputfile.
ENDIF.

" 删除临时文件
DELETE DATASET lv_inputfile  .
DELETE DATASET lv_outputfile .

CALL FUNCTION 'SCMS_BASE64_ENCODE_STR'
  EXPORTING
    input  = lv_output
  IMPORTING
    output = lv_base64.

WRITE: / lv_base64.

0 人点赞