星期一, 11月 06, 2023

2005-04-18 如何於 RPG 中取得 message authentication code(MAC) 碼?


如何於 RPG 中取得 message authentication code(MAC) 碼?

線上交易資料交換頻繁, 前二期, 介紹了 XOR, MD5, 此期介紹 
message authentication code(MAC), 這是金融業主機資料傳輸
最常用的資料檢核方法, 於 AS/400 上, 從 V5R2起系統開始提
供產生 MAC 的 API, Calculate MAC (QC3CALMA, Qc3CalculateMAC),範例如下:


File  : QRPGLESRC
Member: GENMACR
Type  : RPGLE
Usage : CRTBNDRPG GENMACR
OS    : V5R2 (若使用上有問題, 請確認 QSYS/QC3CALMA 程式有存在, 若不存在, 
        請安裝 IBM V5R2 要上 PTF#: SI10060 SI10105)


      * if you want use procedure call(Qc3CalculateMAC), you need
      * use option 15, create module , then
      * CRTPGM PGM(lib/GENMACR) BNDSRVPGM(QC3MAC) and with following
      * H Spec and D Spec
     H*DEBUG  OPTION(*SRCSTMT:*NODEBUGIO)
     D*GenMacPr        PR                  ExtProc('Qc3CalculateMAC')
      *
     H DEBUG  OPTION(*SRCSTMT:*NODEBUGIO) DFTACTGRP(*NO) ACTGRP(*CALLER)
     H BNDDIR('QC2LE')
     D cvthex1To2      PR                  extproc('cvthc')
     D  longReceiver                   *   value
     D  shortSource                    *   value
     D  receiverBytes                10i 0 value

     D cvthex2To1      PR                  extproc('cvtch')
     D  shortReceiver                  *   value
     D  longSource                     *   value
     D  sourceBytes                  10i 0 value

     D*GenMacPr        PR                  ExtProc('Qc3CalculateMAC')
     D GenMacPr        PR                  ExtPgm('QC3CALMA')
     D  InpDta                     1024
     D  InpDtaLen                    10I 0
     D  InpDtaFmt                     8
     D  AlgDesc                             like(ALGD0200)
     D  AlgdFmt                       8
     D  KeyDesc                             like(KEYD0200)
     D  KeyFmt                        8
     D  CrypSrv                       1
     D  CrypDev                      10
     D  MacCode                       8
     D  errcde                              like(APIERR)
     D
     D*ALGD0200 algorithm description structure
     DALGD0200         DS
     D QC3BCA                  1      4B 0
     D*                                             Block Cipher Alg
     D QC3BL                   5      8B 0
     D*                                             Block Length
     D QC3MODE                 9      9             inz('1')
     D*                                             Mode
     D QC3PO                  10     10             inz('0')
     D*                                             Pad Option
     D QC3PC                  11     11             inz(x'00')
     D*                                             Pad Character
     D QC3ERVED               12     12             inz(x'00')
     D*                                             Reserved
     D QC3MACL                13     16B 0
     D*                                             MAC Length
     D QC3EKS                 17     20B 0
     D*                                             Effective Key Size
     D QC3IV                  21     52
     D*                                             Init Vector
     D*KEYD0200 key description format structure
     DKEYD0200         DS
     D*                                             Qc3 Format KEYD0200
     D QC3KT                   1      4B 0
     D*                                             Key Type
     D QC3KSL                  5      8B 0
     D*                                             Key String Len
     D QC3KF                   9      9             inz('0')
     D*                                             Key Format
     D QC3ERVED02             10     12             inz(x'000000')
     D*                                             Reserved
     D QC3KS                  13     20
     D*
     D*                                variable length
      * API error structure
     D APIERR          DS
     D  ERRPRV                       10I 0 INZ(272)
     D  ERRLEN                       10I 0
     D  EXCPID                        7A
     D  RSRVD2                        1A
     D  EXCPDT                      256A
      *
     D  InpDta         S           1024
     D  InpDtaLen      S             10I 0
     D  InpDtaFmt      S              8    inz('DATA0100')
     D  AlgdFmt        S              8    inz('ALGD0200')
     D  KeyFmt         S              8    inz('KEYD0200')
     D  CrypSrv        S              1    inz('1')
     D  CrypDev        S             10
     D  MacCode        S              8
     D  MacCode4       S              4
     D  MacHexCode     S              8
     D  DataSrc        S           1024
     D  DataSrcLen     S             10I 0
     D  Icv16          S             16
     D  Icv08          S              8
     D  IcvLen         S             10I 0
     D  Key16          S             16
     D  Key08          S              8
     D  ErrorMsgId     S              7

     C     *Entry        Plist
     C                   Parm                    DataSrc
     C                   Parm                    Key16
     C                   Parm                    Icv16
     C                   Parm                    MacHexCode
     C                   Parm                    ErrorMsgId
     C
     C                   eval      DataSrcLen =  %len(%trim(DataSrc))
     C                   If        %rem(DataSrcLen : 2) > 0
     C                   eval      DataSrc =  %trim(DataSrc) + '0'
     C                   EndIf
     C
      * Convert 2 Hex chars to 1 Char
     C                   callp     cvthex2To1 (%addr(InpDta)
     C                                       : %addr(DataSrc)
     C                                       : %len(%trim(DataSrc)))


     C                   eval      QC3BCA  = 20
     C                   eval      QC3BL   = 8
     C                   eval      QC3MACL = 8
     C                   eval      QC3EKS  = 0

     C                   eval      Icv16   = %xlate(' ': '0' : icv16)
     C                   callp     cvthex2To1 (%addr(Icv08)
     C                                       : %addr(Icv16)
     C                                       : %len(%trim(Icv16)))
     C
     C                   eval      QC3IV   = Icv08

     C                   eval      QC3KT   = 20
     C                   eval      QC3KSL  =  8
     C                   callp     cvthex2To1 (%addr(Key08)
     C                                       : %addr(Key16)
     C                                       : %len(%trim(Key16)))
     C                   eval      QC3KS   = Key08

     C                   eval      InpDtaLen = %len(%trim(InpDta))
     C
     C                   Callp     GenMacPr(
     C                               InpDta    :
     C                               InpDtaLen :
     C                               InpDtaFmt :
     C                               AlgD0200  :
     C                               AlgdFmt   :
     C                               KeyD0200  :
     C                               KeyFmt    :
     C                               CrypSrv   :
     C                               CrypDev   :
     C                               MacCode   :
     C                               ApiErr )

     C                   If          ERRLEN  = 0
     C                   eval        MacCode4 = MacCode
      * Convert 1 Char to 2 Hex chars
     C                   callp     cvthex1To2 (%addr(MacHexCode)
     C                                       : %addr(MacCode4)
     C                                       : %len(MacCode4)* 2)
     C                   eval        ErrorMsgId = *Blanks
     C                   Else
     C                   eval        MacHexCode = *Blanks
     C                   eval        ErrorMsgId = EXCPID
     C                   EndIf
     C                   eval        *InLr = *On




測試範例

File  : QRPGLESRC
Member: GENMACTEST
Type  : RPGLE
Usage : CRTBNDRPG GENMACTEST
        CALL GENMACTEST
OS    : V5R2 


     H DEBUG  OPTION(*SRCSTMT:*NODEBUGIO) DFTACTGRP(*NO) ACTGRP(*CALLER)
     D  DataSrc        S           1024
     D  Icv16          S             16
     D  Key16          S             16
     D  MacHexCode     S              8
     D  ErrorMsgId     S              7

     D  GenMacR        PR                  ExtPgm('GENMACR')
     D   DataSrc                   1024
     D   Key16                       16
     D   Icv16                       16
     D   MacHexCode                   8
     D   ErrorMsgId                   7

     C                   eval      Key16   = 'E07DDB948C3F2D44'
      * MACCode: 1BB5AD90
     C                   eval      DataSrc =
     C                              '574365400000005000000456655687845'
     C                   eval      Icv16   = '20040625105948'
     C                   ExSr      GenMacSr

      * MACCode: DBB695DD
     C                   eval      DataSrc =
     C                              '546646800000010000005644651386983'
     C                   eval      Icv16   = '20040625110002'
     C                   ExSr      GenMacSr

      * MACCode: 1181D5A9
     C                   eval      DataSrc =
     C                              '689563200000015000006563232565543'
     C                   eval      Icv16   = '20040625110025'
     C                   ExSr      GenMacSr

      * MACCode: 24AC4268
     C                   eval      DataSrc =
     C                             '56989876564645646600000005000310686-
     C                             8542536988'
     C                   eval      Icv16   = '20040625110212'
     C                   ExSr      GenMacSr

      * MACCode: 00FC6820
     C                   eval      DataSrc =
     C                             '65523591235858665400000015000110511-
     C                             3235463238'
     C                   eval      Icv16   = '20040625110220'
     C                   ExSr      GenMacSr

      * MACCode: FBC4650E
     C                   eval      DataSrc =
     C                             '65522332325465384100000010000110122-
     C                             4323235858'
     C                   eval      Icv16   = '20040625110232'
     C                   ExSr      GenMacSr

      * MACCode: 23B09440                                               
     C                   eval      DataSrc =                            
     C                             '104117700000000600000112011274664'  
     C                   eval      Icv16   = '20050725101431'           
     C                   ExSr      GenMacSr                             
                                                                        
      * MACCode: 5E8104EC                                               
     C                   eval      DataSrc =                            
     C                             '222759300000000300002792020001542'  
     C                   eval      Icv16   = '20050725101549'           
     C                   ExSr      GenMacSr                             

     C                   eval        *InLr = *On
     C**********************************************************************
     C     GenMacSr      BegSr
     C                   eval      MacHexCode = *Blanks
     C                   eval      ErrorMsgId = *Blanks
     C                   Callp     GenMacR(
     C                               DataSrc    :
     C                               Key16      :
     C                               Icv16      :
     C                               MacHexCode :
     C                               ErrorMsgId )
     C
     C                   If        ErrorMsgId = *Blanks
     C     MAcHexCode    Dsply
     C                   Else
     C     ErrorMsgId    Dsply
     C                   EndIf

     C                   EndSr
     C**********************************************************************





沒有留言: