× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Thank you so much Scott! This really worked for me.
I always had a suspect on handling of key in the program. But now it worked with your code :-)
Thanks,Mahesh Angadi On Thursday, January 4, 2024 at 06:09:32 PM GMT+1, Scott Klement <rpg400-l@xxxxxxxxxxxxxxxx> wrote:

Hello Mahesh,

The problem is the key you're providing is encoded as a text file, it
looks like CER format.  But you are telling the API that the key is in
BER format.  To convert between them, all you should need to do is
extract everything the '----begin public key---' and the '---end public
key---' and then base64 decode it.  That should give you the binary
version of it.

There's no way I could have determined that from your code, however,
because you deliberately changed parts of the token and the key, which
made it impossible for anyone to test your program.

To solve that problem, I replaced your token and private key with the
public example found here (make sure you change the algorithm to RS256
to match the way your program has been coded):   https://jwt.io/
In case anyone would like to try it, here is the code that I came up
with.  This code works for me:


**FREE


    ctl-opt dftactgrp(*no) bnddir('BASE64') option(*srcstmt: *nodebugio);
    /copy base64_h

// Entry Parameters
    dcl-pi *n ;
        token like(jwt_token_t) const;
        success like(jwt_success_t) const;
    end-pi;

    dcl-pr verifySignature ExtProc('Qc3VerifySignature');
        // Signature Details
        signature      Char(4096) ccsid(*hex) const; // fingerprInt
        signatureLen   Int(10) const;
        // Original Data Details
        Data           Char(8000) ccsid(*utf8) const; // original data
        Datalen        Int(10) const;
        Dataformat     Char(8) const;    //DATA0100 = data directly
        // encryption algo -> RSA
        Algo           char(32767) options(*varsize :*omit);
        AlgoFormat     Char(8) const; //ALGD0400 = key parameters
        Key            char(32767) options(*varsize :*omit) const;
        KeyFormat      Char(8) const;    //KEYD0600 = use key from PEM
        CSPcertificate Char(1) const;    // 1=Soft,2=hard(fill in
DEVICE),0=
        CSPDEVICE      Char(10) const;   // blank if no co-processor
        ApiError       likeds(ApiError);
    end-pr;
    dcl-ds payload_json qualified;
        iss         char(256);
        aud         char(256);
        exp         zoned(10:0);
        nbf         zoned(10:0);
        client_id   char(100);
        scope       char(10);
    end-ds;

    dcl-ds header_json qualified;
        typ         char(10);
        alg         char(10);
        x5t         char(50);
        kid         char(50);
    end-ds;

    dcl-ds ApiError qualified inz;
        BytPrv    int(10) inz(%Size(ApiError));
        BytAvl    int(10) inz(0);
        MsgId     char(7);
        *n        char(1);
        MsgDta    char(128);
    end-ds ApiError;
    dcl-ds algoDS qualified;
        PublicKeyAlgorithm        int(10);
        PKABlockFormat            char(1);
        Reserved                  char(3) inz(X'000000');
        SigningHashAlgorithm      int(10);
    End-Ds;
    dcl-ds KeyD0200 qualified;
        KeyType                int(10);
        KeyStringLen           int(10);
        KeyFormat              char(1);
        Reserved               char(3);
        KeyString              char(2400) ccsid(*hex);
    end-ds KeyD0200;

    // Templates
    dcl-s jwt_token_t varchar(10000) ccsid(*utf8) template;
    dcl-s valid ind inz(*off);

    dcl-s jwt_token like(jwt_token_t);
    dcl-s header like(jwt_token_t);
    dcl-s payload like(jwt_token_t);
    dcl-s datatocheck like(jwt_token_t);
    dcl-s json pointer;
    dcl-s jwt_success_t  Ind Inz(*Off);
    dcl-s UTF8_PERIOD char(1) inz('.') ccsid(*utf8);
    dcl-s data like(jwt_token_t) ccsid(*utf8);
    dcl-s Signature       char(1000) ccsid(*hex);
    dcl-s SignatureLen    int(10);
    dcl-s utfcomma  Char(1) inz('.');
    dcl-s payloadPos   int(10);
    dcl-s publickey varchar(5000);
    dcl-c LF x'25';

    dcl-s publickeyb64 varchar(500);
    dcl-s KeyStart     int(10);
    dcl-s KeyEnd       int(10);
    dcl-s KeyLen       int(10);

    dcl-s DataLen Int(10);
    dcl-c DATA0100_FMT          'DATA0100';
    dcl-c KEYD0200_FMT          'KEYD0200';
    dcl-c ALGD0400_FMT          'ALGD0400';
    dcl-c ANYCSP                '0';
    dcl-c RSAPUBLICKEYALGORITHM 50;
    dcl-c PKCS1                 '1';
    dcl-c BERSTRING            '1';
    dcl-s JwtArray  like(jwt_token) dim(3);
    monitor;
        jwt_token =
          'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0' +
          'NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsI' +
          'mlhdCI6MTUxNjIzOTAyMn0.NHVaYe26MbtOYhSKkoKYdFVomg4i8Z' +
          'Jd8_-RU8VNbftc4TSMb4bXP3l3YlNWACwyXPGffz5aXHc6lty1Y2t' +
          '4SWRqGteragsVdZufDn5BlnJl9pdR_kdVFUsra2rWKEofkZeIC4yW' +
          'ytE58sMIihvo9H1ScmmVwBcQP6XETqYd0aSHp1gOa9RdUPDvoXQ5o' +
          'qygTqVtxaDr6wUFKrKItgBMzWIdNZ6y7O9E0DhEPTbE9rfBo6KTFs' +
          'HAZnMg4k68CDp2woYIaXbmYTWcvbzIuHO7_37GT79XdIwkm95QJ7h' +
          'YC9RiwrV7mesbY4PAahERJawntho0my942XheVLmGwLMBkQ';

        publickey =
            '-----BEGIN PUBLIC KEY-----' + LF
          +
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo' + LF
          +
'4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u' + LF
          +
'+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyeh' + LF
          +
'kd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ' + LF
          +
'0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdg' + LF
          +
'cKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbc' + LF
          + 'mwIDAQAB' + LF
          + '-----END PUBLIC KEY-----';

        JwtArray = %split(jwt_token :UTF8_PERIOD);
        // Get the header information
        header = decodeBase64( JwtArray(1) );
        data-into header_json
            %DATA(header :'case=convert allowmissing=yes allowextra=yes')
            %PARSER('YAJLINTO');

        // Get the payload information
        payload = decodeBase64( JwtArray(2) );
        data-into payload_json
            %DATA(payload :'case=convert allowmissing=yes allowextra=yes')
            %PARSER('YAJLINTO');

        // Get the Signature information
        Signature = decodeBase64( JwtArray(3) );
        SignatureLen = %len(%trim(Signature));

        datatocheck = JwtArray(1) + '.' +JwtArray(2);
        dataLen = %len(%trimr(datatocheck));

        algoDS = *allx'00';
        algoDS.PublicKeyAlgorithm = RSAPUBLICKEYALGORITHM;
        algoDS.PKABlockFormat = PKCS1;
        // 3=SHA256 5=SHA512
        algoDS.SigningHashAlgorithm = 3;

        KeyD0200 = *allx'00';
        KeyD0200.KeyType      = RSAPUBLICKEYALGORITHM;
        KeyD0200.KeyFormat    = BERSTRING;

        // Extract the data portion of the public key.

        KeyStart = %scan('-----' + LF: publickey) + %len('-----' + LF);
        KeyEnd   = %scan(LF + '-----': publickey);
        KeyLen   = KeyEnd - KeyStart;
        PublicKeyB64 = %subst(PublicKey:KeyStart:KeyLen);
        PublicKeyB64 = %scanrpl(LF: '': PublicKeyB64);

        // The Data portion of the public key is base64-encoded, so
        // decode it.

        KeyD0200.KeyStringLen = base64_decode( %addr(publickeyb64:*data)
                                             : %len(publickeyb64)
                                             : %addr(KeyD0200.KeyString)
                                             : %size(KeyD0200.KeyString));

        // IBM Crypto API.
        // Qc3VerifySignature will send ESCAPE message if in case it fails
        verifySignature(  signature
                        : signatureLen
                        : DatatoCheck
                        : dataLen
                        : DATA0100_FMT
                        : algoDS
                        : ALGD0400_FMT
                        : KeyD0200
                        : KEYD0200_FMT
                        : ANYCSP
                        : ''
                        : ApiError);

        if Apierror.MsgId <> ' ';
            jwt_success_t = *off;
            return;
        endif;
        // On success we return as below:
        jwt_success_t = *On;
        return;
    on-error;
        // If the given token is with wrong strucutre, base64 will fail.
        jwt_success_t = *off;
        return;
    endmon;

    dcl-proc decodeBase64;
        dcl-pi *n varchar(65530) ccsid(1208);
            string varchar(65530) const ccsid(*utf8);
        end-pi;

        dcl-s workstring varchar(65530) ccsid(*utf8);
        dcl-s DecodeString varchar(65530);
        dcl-s DecodedString_utf8 varchar(65530) ccsid(*utf8) ;
        dcl-s DecodedString_utf8_length int(10);

        dcl-s DecodedString_Hex    varchar(65530) ccsid(*hex);
        dcl-s FROMB64             char(2) inz('+/') ccsid(*utf8);
        dcl-s TOB64               char(2) inz('-_') ccsid(*utf8);
        dcl-s UGUALEFILL          char(2) inz('==') ccsid(*utf8);
        dcl-s Remainder           int(10);

        workstring = %trimr(string);

        // Trasformo in base64url
        workstring = %xlate( TOB64 :FROMB64 :workstring);
        Remainder = %len(workstring);
        Remainder = (%rem(%len(workstring) :4));

        select;
            // when (Remainder = 1);
            //   StringToDecodedWork = StringToDecodedWork + UGUALEFILL;
            when (Remainder = 2);
                workstring = workstring + UGUALEFILL;
            when (Remainder = 3);
                workstring = workstring + %subst(UGUALEFILL :1 :1);
        endsl;

        // Decoding
        DecodeString = %trimr(workstring);
        %len(DecodedString_utf8) = %len(DecodedString_utf8:*max);

        DecodedString_utf8_length = base64_decode( %addr(DecodeString :
*data)
                                                 : %len(DecodeString)
                                                 :
%addr(DecodedString_utf8:*data)
                                                 :
%len(DecodedString_utf8:*max) );
        DecodedString_Hex = DecodedString_utf8;
        return DecodedString_utf8;
    end-proc;



On 1/4/2024 3:32 AM, Mahesh Angadi via RPG400-L wrote:
 
With referenceto above code, I have made up my own program as below to test and make it workbut never succeeded.

For testingpurpose, I have hard coded my Token and Key in the program but

My suspectis the way I am sending the Public Key to 'Qc3VerifySignature'.


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.