ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Qc3DecryptData - will not decode random encoded values

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Qc3DecryptData - will not decode random encoded values

    for the most part, the two apis, work fine with most data...

    Qc3DecryptData Decrypt data Restores encrypted data to a
    clear (intelligible) form.

    Qc3EncryptData Encrypt data Scrambles clear data into an
    unintelligible form.


    I wrote a test wrapper outside of my FIELDPROC to make a call to encode the a string parm and then decode it (and write both values to joblog)...

    Assume most (say 9 out of 10) values I pass it encode/decode correctly... however when I pass it a '00357560', or '0045221', or '00425043' for example, it creates the encode string for it no problem but cannot turn around and decode the encoded string....??


    I'll first start with a correct run from a value it has not problem with...

    call enc938tstr ('0357561' '0007')

    R¹!ç»C®°Y°'ë}o <-- encoded value generates
    0357561 <-- uses encoded value to turn around and decode back to original value

    Now, change one digit to use a value I have issues with...

    call enc938tstr ('0357560' '0007')

    5ÑsüõE*;ø·ÓòuúT <-- encoded value generates
    <-- cannot decoded value based on encoded value

    In debug, the Qc3DecryptData returns an error... unfortunately i am unable to debug further...


    DecryptData( PxCphStr
    : %Len( PxCphStr )
    : ALGD0200
    : 'ALGD0200'
    : KEYD0400
    : 'KEYD0400'
    : CSP_SFW
    : *Blanks
    : RtnDtaStr
    : %Size( RtnDtaStr )
    : RtnDtaLen
    : ERRC0100
    );

    If ERRC0100.BytAvl > *Zero;
    Return NULL;
    endif;

    ERRC0100.BytAvl = 15

    Anyone have any suggestions?










  • #2
    The first and most obvious question is - so what is the error code? If there are 15 bytes of info in ERRC0100 what are they? 15 seems a low number by the way - what value did you initially place in bytes provided?

    The other thing is that we don't know how your wrapper defines its parms. Passing a character string to be translated (first parm) is expected. But the second parm, which appears to be the length of the first, you have coded it as a character literal not as a numeric which - while not impossible seems really odd.

    For that matter while you have shown us how you are calling Qc3DecryptData we don't see how you are calling Qc3EncryptData nor for that matter how any of the passed parms are defined.

    I know this may all sound silly but the reason for mentioning it is that when playing with these APIs in the past I managed to get similar results - but it turned out that _all_ my calls were in fact wrong. But just by luck sometimes they worked!

    Comment


    • #3
      thank you jonboy... here is all the info and more that I think you should need...


      from the wrapper...

      // encrypt data string
      d enc938r_encDtaStr...
      d pr 1024 varying
      d pxDtaStr 1024 varying const
      d pxKeyStore 20 const
      d pxKeyLabel 10 const

      // decrypt cipher string:
      d enc938r_decCphStr...
      d pr 1024 varying
      d pxCphStr 1024 varying const
      d pxKeyStore 20 const
      d pxKeyLabel 10 const

      d g_inpDtaVar s 1024 varying
      d g_outDtaVar s 1024 varying
      d g_keyStore...
      d s 20 inz('ISGNKEYST1LDCRYPTO ')
      d g_keyLabel...
      d s 10 INZ('ISGN01')

      //------------------------------------------------
      // encode the incoming parm text value...
      g_inpDtaVar = %subst(p_inData:1_length);
      g_outDtaVar = enc938r_encDtaStr(%trim(g_inpDtaVar)
      :g_keyStore
      :g_keyLabel);
      writeToJoblog(%trim(g_outDtaVar));

      //------------------------------------------------
      // decode the encoded value...
      g_outDtaVar = enc938r_decCphStr(%trim(g_outDtaVar)
      :g_keyStore
      :g_keyLabel);
      writeToJoblog(%trim(g_outDtaVar));


      now for the crypto api itself...


      **-- Block cipher algorithm description:
      D ALGD0200 Ds Qualified
      D BlkCphAlg 10i 0
      D BlkLen 10i 0
      D Mode 1a
      D PadOpt 1a
      D PadChr 1a
      D Rsv 1a
      D MacLen 10i 0
      D EfcKeySiz 10i 0
      D InzVct_IV 32a
      **-- Key description:
      D KEYD0400 Ds Qualified
      D keyname 20 inz
      D keyrecord 32 inz
      D rsvd 4 inz(X'00000000')

      D RtnDtaStr s 1024
      D RtnDtaLen s 10i 0
      D NULL c ''

      /Free

      ALGD0200.BlkCphAlg = AES;
      ALGD0200.BlkLen = 16;
      ALGD0200.Mode = ECB;
      ALGD0200.PadOpt = PAD_CHR;
      ALGD0200.PadChr = x'00';
      ALGD0200.Rsv = x'00';
      ALGD0200.MacLen = *Zero;
      ALGD0200.EfcKeySiz = *Zero;
      ALGD0200.InzVct_IV = *Allx'00';

      KEYD0400.Keyname = pxKeyStore;
      KEYD0400.Keyrecord = pxKeyLabel;
      KEYD0400.Rsvd = *Allx'00';

      DecryptData( PxCphStr
      : %Len( PxCphStr )
      : ALGD0200
      : 'ALGD0200'
      : KEYD0400
      : 'KEYD0400'
      : CSP_SFW
      : *Blanks
      : RtnDtaStr
      : %Size( RtnDtaStr )
      : RtnDtaLen
      : ERRC0100
      );

      If ERRC0100.BytAvl > *Zero;
      Return NULL;

      Else;
      Return %Subst( RtnDtaStr: 1: RtnDtaLen );
      EndIf;

      and a closer look at ERRC0100 in debug shows this...

      EVAL errc0100
      ERRC0100.BYTPRV = 1040
      ERRC0100.BYTAVL = 15
      ERRC0100.MSGID = 'CPF9DD6'
      ERRC0100 = '0'
      ERRC0100.MSGDTA =
      ....5...10...15...20...25...30...35...40...45...50 ...55...60
      1 ' '
      61 ' '
      121 ' '
      181 ' '
      241 ' '
      301 ' '
      361 ' '


      and the help at the below link says...
      CPF9DD6 E Length of area provided for output data is too small.
      https://www.ibm.com/support/knowledg...s/qc3decdt.htm


      But why? and why does it work for '0357561' and not '0357560'?


      pretty sure I see the issue - the parm from the wrapper to the api is 1024 varying.

      When i view the parm in the wrapper just before passing to api, it looks good...

      EVAL g_inpDtaVar:c 1024
      G_INPDTAVAR:C 1024 =
      ....5...10...15...20...25...30...35...40...45...50 ...55...60
      1 ' 0357560 '
      61 ' '
      121 ' '
      181 ' '
      241 ' '
      301 ' '
      361 ' '
      421 ' '
      481 ' '
      541 ' '
      601 ' '


      however, when i look at the api receiving parm as soon as I step into it, it shows this garbage.
      This is why I don't like varying length fields (or just shows my lack of understanding them)... how do I prevent this???

      EVAL pxdtastr:c 1024
      PXDTASTR:C 1024 =
      ....5...10...15...20...25...30...35...40...45...50 ...55...60
      1 ' 0357560 Ø Onv Æ Ø On'
      61 'v ¸ØØ Onv ¸Ú Ø Onv Æ&Ø '
      121 '½{ Ø ½{ Ø ½{ QSYS'
      181 '/QTESESSH '
      241 'EU Ø 4Ï=J Ø QTESESSH'
      301 ' QTESESSH H QTECNTDB QRNS4SEU '
      361 ' 2Í,m ³Ø 2Í,m ÚØ '
      421 ' 2Í,m Ø 2Í,m Ø 2Í,m Ø 2Í,m '
      481 'Ø 2Í,m Ø 2Í,m Ø 2Í,m Ø 2Í,m'
      541 ' ìØ 2Í,m ßØ Onv Æ^Ø 2Í,m $Ø '
      601 'Onv Æ}Ø 2Í,m ÑØ 2Í,m 7 2Í,m ÙØ '
      More..

      bahhhh, and second thought not sure this is the issue... in debug, before the api gets called, i'm cleaning up the contents of the variable by clearing the remainder of the string behind the value (and the encoded value on the decoded call)... still same result and same error message???? I don't get it.
      Last edited by jayvaughn; October 3, 2017, 07:32 AM.

      Comment


      • #4
        Sorry - travelling all day today.

        BUT - if an API is expecting a regular character field (which it is) you cannot pass it a varying length field and expect it to work without some precautions.

        will try to look at your code tonight.

        Comment


        • #5
          Originally posted by JonBoy View Post
          Sorry - travelling all day today.

          BUT - if an API is expecting a regular character field (which it is) you cannot pass it a varying length field and expect it to work without some precautions.

          will try to look at your code tonight.
          thanks... so you are right... below is the latest issue... (basically trying to get fixed vs varying to work)...

          Ok, here is the issue below?
          See the ?// This Doesn?t Work and // This Does Work?

          The reason I am so determined to put the encoded value back into a fixed 1024 is because that?s what the FIELDPROC parm that interfaces with the database is. If I have to change it to varying, then I have a bit of other code to change to play well with the varying vs. fixed behavior. So really trying to avoid that? If you can?t think of anything let me know? I?m working on some solution to get it to work with the fixed?


          d g_wrkDtaFix s 1024 inz
          d g_inpDtaVar s 1024 varying inz
          d g_outDtaVar s 1024 varying inz


          //------------------------------------------------
          // encode the incoming parm text value...
          g_inpDtaVar = %subst(p_inData:1_length);
          g_outDtaVar = enc938r_encDtaStr(g_inpDtaVar
          :g_keyStore
          :g_keyLabel
          :g_rtnLen);
          g_wrkDtaFix = g_outDtaVar;
          writeToJoblog(%trim(g_wrkDtaFix));

          //------------------------------------------------
          // decode the encoded value...
          g_inpDtaVar = g_wrkDtaFix;

          //g_outDtaVar = enc938r_decCphStr(g_inpDtaVar // doesn't work
          g_outDtaVar = enc938r_decCphStr(g_outDtaVar // does work
          :g_keyStore
          :g_keyLabel
          :g_rtnLen);
          writeToJoblog(%trim(g_outDtaVar));

          *inlr = *on;














          Comment


          • #6
            Do some reading on Varying length fields - I've written a number of articles but my roadtrip bathroom break is too short to look them up for you!

            If you code CONST on an RPG prototype, you can pass in a varying or fixed field and the compiler takes care of it for you.

            You can use varying when fixed is expected by passing in the address of the *DATA portion of the field e.g. %Addr(varyfield: *Data)

            Since the APIs you are using require a length and return a length you can use %Len to obtain the current length _and_ to set the vary field's length after the call.

            Just a few thoughts that might trigger something in the grey matter for you.

            Comment


            • #7
              Originally posted by JonBoy View Post
              Do some reading on Varying length fields - I've written a number of articles but my roadtrip bathroom break is too short to look them up for you!

              If you code CONST on an RPG prototype, you can pass in a varying or fixed field and the compiler takes care of it for you.

              You can use varying when fixed is expected by passing in the address of the *DATA portion of the field e.g. %Addr(varyfield: *Data)

              Since the APIs you are using require a length and return a length you can use %Len to obtain the current length _and_ to set the vary field's length after the call.

              Just a few thoughts that might trigger something in the grey matter for you.
              thank you very much for keeping me going... you know... this is all because IBM let spaces be a char in their 16 char encoding string.

              Comment


              • #8
                let me ask this... this may clear up my entire dilemma... when the qc3encryptData produces the encoding, will it ALWAYS be 16 chars?

                assuming i am using AES and have my block length set to 16... will it ever be less?
                Last edited by jayvaughn; October 3, 2017, 02:19 PM.

                Comment


                • #9
                  Can I decrypt the sample data present in sample input XML file for field called encodedtokenexchange using this API if yes could you please provide sample code for the same?
                  Attached Files

                  Comment


                  • #10
                    Apart from this I tried OPENSSL command in interactive way there it works quite well but in programmatic way it's not working as per expectation. please find sample program for the same:-
                    I have also tried 'Qc3DecryptData' from IBM website and uploading sample program for that as well it's also not working. openssl in interactive way :-

                    1) CHGJOB CCSID (37)
                    2) CALL QSYS/QP2TERM
                    3) echo 'u3VtNgfyWU9faZc3Iaa8ZWbE5UZCfmC17yA4MyW0ghflt9dNQ NDpCcgMZiG/kXPE4vv2CHL
                    93B4iKiODHxxdVA==' | openssl enc -d -aes-128-ecb -K 363631653237354f494d31554
                    c594c4a -nopad -nosalt -base64 -A

                    Decrypted value on console comes like :-707fbe32-0dbc-41e0-888f-5bc40de8c20d2P9AMPCTQ4CZ ¢

                    Attached Files

                    Comment


                    • #11
                      uploaded sample input XML file as well whose field called 'encodedexchangetoken' my program is trying to decrypt.

                      Comment


                      • #12
                        any updates by iseries experts on the same please?

                        Comment


                        • #13
                          Your interactive command is not the same as your RPG command. In RPG you've specified "-out record" which tells it to write to a file named record... not sure why you're doing that.

                          I tried it without the "-out record" and it worked perfectly.

                          Comment

                          Working...
                          X