본문 바로가기
ABAP/Function|Class

[Class] CL_SEC_SXML_WRITER - AES256 암호화/복호화

by name_text 2023. 11. 30.

CL_SEC_SXML_WRITER

AES256 암호화/복호화

 

알고리즘별로 KEY 길이를 잘 맞추어야 합니다.

AES128 : Block size = 16

AES192 : Block size = 24

AES256 : Block size = 32

# 사용예시

PARAMETERS: P_PLAIN TYPE STRING OBLIGATORY,
            P_KEY   TYPE STRING OBLIGATORY,
            P_IV    TYPE STRING OBLIGATORY.

INITIALIZATION.
  %_P_PLAIN_%_APP_%-TEXT = '평문'.
  %_P_KEY_%_APP_%-TEXT = 'Secret Key'.
  %_P_IV_%_APP_%-TEXT = 'Initialization Vector'.

START-OF-SELECTION.

  "키 길이 맞춰야 함 (AES256 blocksize 32)
  DATA(LV_KEY) = CL_BCS_CONVERT=>STRING_TO_XSTRING( CONV #( P_KEY ) ).
  CL_SEC_SXML_WRITER=>PKCS7_PADDING( exporting BLOCKSIZE = 32
                                     changing  DATA      = LV_KEY ).
  LV_KEY = LV_KEY(32).

  "Initialization Vector (Blocksize 16)
  DATA(LV_IV) = CL_BCS_CONVERT=>STRING_TO_XSTRING( CONV #( P_IV ) ).
  CL_SEC_SXML_WRITER=>PKCS7_PADDING( exporting BLOCKSIZE = 16
                                     changing  DATA      = LV_IV ).
  LV_IV = LV_IV(16).

  "암호화
  CL_SEC_SXML_WRITER=>ENCRYPT_IV(
    exporting
      PLAINTEXT  = CL_BCS_CONVERT=>STRING_TO_XSTRING( CONV #( P_PLAIN ) )
      KEY        = LV_KEY
      IV         = LV_IV
      ALGORITHM  = CL_SEC_SXML_WRITER=>CO_AES256_ALGORITHM_PEM
    importing
      CIPHERTEXT = DATA(LV_CIPHERTEXT)    " Ciphertext
  ).
  DATA(LV_CIPHERTEXT_B) = LV_CIPHERTEXT+16.   "Initialization Vector 제거(외부 시스템과의 통신을위해 INIT VECTOR 제거)


  "복호화
  "복호화를 위해 Initialization Vector와 암호화문 결합
  LV_CIPHERTEXT = LV_IV && LV_CIPHERTEXT_B.

  CL_SEC_SXML_WRITER=>DECRYPT(
    exporting
      CIPHERTEXT = LV_CIPHERTEXT
      KEY        = LV_KEY
      ALGORITHM  = CL_SEC_SXML_WRITER=>CO_AES256_ALGORITHM_PEM
    importing
      PLAINTEXT  = DATA(LV_XSTR)
  ).


  CL_DEMO_OUTPUT=>NEW(
    )->NEXT_SECTION( 'Original Text' )->WRITE( P_PLAIN
    )->NEXT_SECTION( 'Key' )->WRITE( P_KEY
    )->NEXT_SECTION( 'Key X' )->WRITE( LV_KEY
    )->NEXT_SECTION( 'Initialization Vector' )->WRITE( P_IV
    )->NEXT_SECTION( 'Initialization Vector X' )->WRITE( LV_IV
    )->NEXT_SECTION( 'ENCRYPT' )->WRITE( LV_CIPHERTEXT_B
    )->NEXT_SECTION( 'ENCRYPT BASE64' )->WRITE( CL_HTTP_UTILITY=>ENCODE_X_BASE64( LV_CIPHERTEXT_B )
    )->NEXT_SECTION( 'DECRYPT' )->WRITE( CL_BCS_CONVERT=>XSTRING_TO_STRING(
                                                        IV_XSTR   = LV_XSTR
                                                        IV_CP     = 4110 )
    )->DISPLAY( ).
ABAP

 

 

#해당 로직을 Class로 만들면 다음과 같이 할 수 있습니다.

class LCL_AES_WRITER definition.

public section.
  constants CO_AES128 type STRING value CL_SEC_SXML_WRITER=>CO_AES128_ALGORITHM_PEM ##NO_TEXT.
  constants CO_AES192 type STRING value CL_SEC_SXML_WRITER=>CO_AES192_ALGORITHM_PEM ##NO_TEXT.
  constants CO_AES256 type STRING value CL_SEC_SXML_WRITER=>CO_AES256_ALGORITHM_PEM ##NO_TEXT.

  class-methods AES_ENCRYPT_STRING
    importing
      !IV_PLAINTEXT type CSEQUENCE
      !IV_KEY type CSEQUENCE
      !IV_INIT_VECTOR type CSEQUENCE optional
      !IV_ALGORITHM type STRING default CO_AES256
    exporting
      !EV_CIPHERTEXT type XSTRING
    returning
      value(RV_CIPHERTEXT_BABE64) type STRING .
  class-methods AES_DECRYPT_STRING
    importing
      !IV_CIPHERTEXT_BASE64 type STRING
      !IV_KEY type CSEQUENCE
      !IV_INIT_VECTOR type CSEQUENCE optional
      !IV_ALGORITHM type STRING default CO_AES256
    returning
      value(RV_PLAINTEXT) type STRING .
protected section.
private section.

  class-methods PKCS7_PADDING
    importing
      !IV_BLOCKSIZE type I
      !IV_DATA type XSTRING
    returning
      value(RV_DATA) type XSTRING .
ENDCLASS.



CLASS LCL_AES_WRITER IMPLEMENTATION.
  method AES_DECRYPT_STRING.

    "복호화
    "복호화를 위해 Initialization Vector와 암호화문 결합
    DATA(LV_CIPHERTEXT) = CL_HTTP_UTILITY=>DECODE_X_BASE64( IV_CIPHERTEXT_BASE64 ).
    LV_CIPHERTEXT = PKCS7_PADDING( IV_BLOCKSIZE = 16
                                   IV_DATA = CL_BCS_CONVERT=>STRING_TO_XSTRING( CONV #( IV_INIT_VECTOR ) ) )
                    && LV_CIPHERTEXT.

    CL_SEC_SXML_WRITER=>DECRYPT(
      exporting
        CIPHERTEXT = LV_CIPHERTEXT
        KEY        = PKCS7_PADDING( IV_BLOCKSIZE = SWITCH #( IV_ALGORITHM WHEN CO_AES128 THEN 16
                                                                          WHEN CO_AES192 THEN 24
                                                                          WHEN CO_AES256 THEN 32 )
                                    IV_DATA = CL_BCS_CONVERT=>STRING_TO_XSTRING( CONV #( IV_KEY ) ) )
        ALGORITHM  = IV_ALGORITHM
      importing
        PLAINTEXT  = DATA(LV_PLAINTEXT)
    ).

    RV_PLAINTEXT = CL_BCS_CONVERT=>XSTRING_TO_STRING(
                   IV_XSTR   = LV_PLAINTEXT
                   IV_CP     = 4110 ).
  endmethod.

  method AES_ENCRYPT_STRING.
    "암호화
    CL_SEC_SXML_WRITER=>ENCRYPT_IV(
      exporting
        PLAINTEXT  = CL_BCS_CONVERT=>STRING_TO_XSTRING( CONV #( IV_PLAINTEXT ) )
        KEY        = PKCS7_PADDING( IV_BLOCKSIZE = SWITCH #( IV_ALGORITHM WHEN CO_AES128 THEN 16
                                                                          WHEN CO_AES192 THEN 24
                                                                          WHEN CO_AES256 THEN 32 )
                                    IV_DATA = CL_BCS_CONVERT=>STRING_TO_XSTRING( CONV #( IV_KEY ) ) )
        IV         = PKCS7_PADDING( IV_BLOCKSIZE = 16
                                    IV_DATA = CL_BCS_CONVERT=>STRING_TO_XSTRING( CONV #( IV_INIT_VECTOR ) ) ) "Initialization Vector 16자리
        ALGORITHM  = IV_ALGORITHM
      importing
        CIPHERTEXT = DATA(LV_CIPHERTEXT)
    ).
    EV_CIPHERTEXT = LV_CIPHERTEXT+16.   "Initialization Vector 제거

    RV_CIPHERTEXT_BABE64 = CL_HTTP_UTILITY=>ENCODE_X_BASE64( EV_CIPHERTEXT ).
  endmethod.

  method PKCS7_PADDING.
    DATA(LV_DATA) = IV_DATA.
    CL_SEC_SXML_WRITER=>PKCS7_PADDING( exporting BLOCKSIZE = IV_BLOCKSIZE
                                       changing  DATA      = LV_DATA ).

    RV_DATA = LV_DATA(IV_BLOCKSIZE).
  endmethod.
ENDCLASS.
ABAP

댓글