Page 1 of 2

Encode Base64 doesn't return the correct value

Posted: Fri Jul 01, 2022 3:21 pm
by hmauricio
Hello Scott,
i'm using your encode/decode service program to encode a signature returned from the Qc3CalculateSignature API, this is
for generate an Hash for tax purposes, what's happening is that sometimes the returned encoded value is not correct.

I'm enconding the *Hex variable returned from the API, and sometimes not always, the returned value is not correct,
but just the last 3 characters, it ends with "==" the rest of the string is Ok.

I dont know if you can help me on this.

Hex Signature returned from the API: 088A95B2D16E2386B8E0E605715211EE785FF92CE539514904ECEEE815BB73F0D7DC58F2A6B9ECE7B22ED7F453AC69EF55CAC47386CEEF6E0821835D1C8545B91D69F36F7AE74E6F661377AD773CEFD2922C36451FC527AD6B5DB766740AE0F0B4F2B46997C494CE099060A2987EB14B7B465557EF3E1623EEC884DEB9DAA1

Expected Value after Base64 Encode:
CIqVstFuI4a44OYFcVIR7nhf+SzlOVFJBOzu6BW7c/DX3Fjyprns57Iu1/RTrGnvVcrEc4bO724IIYNdHIVFuR1p8296505vZhN3rXc879KSLDZFH8UnrWtdt2Z0CuDwtPK0aZfElM4JkGCimH6xS3tGVVfvPhYj7siE3rnaoUA=

Encoded string received from Encode Service program:
CIqVstFuI4a44OYFcVIR7nhf+SzlOVFJBOzu6BW7c/DX3Fjyprns57Iu1/RTrGnvVcrEc4bO724IIYNdHIVFuR1p8296505vZhN3rXc879KSLDZFH8UnrWtdt2Z0CuDwtPK0aZfElM4JkGCimH6xS3tGVVfvPhYj7siE3rnaoQ==

As you can see only the last characters are wrong, but as i said before this only happends in some signatures, the majority are Ok.

Best Regards
Helder

Re: Encode Base64 doesn't return the correct value

Posted: Fri Jul 01, 2022 3:37 pm
by Scott Klement
How can I reproduce the problem?

Re: Encode Base64 doesn't return the correct value

Posted: Fri Jul 01, 2022 4:10 pm
by hmauricio
Hello Scott,

i've a program that receives a string to be encoded, it call's the Qc3CalculateSignature API and sends that string to
calculate the signature, then with the received signature i'm calling your service program to encode to Base64.

This is the string received that as to be encripted, this string is the one that generates the strings i've sent you before.

I don't know if this helps, i really don't know how you can reproduce the problem, just if you run my program in my PC.

Received string:
2022-05-06;2022-05-06T07:43:08;GR GR1/89922;245.41;h2S0asnn1XUkapcodcE0qE+Fl7f0wC80uX3QXhY1eKfmBYwrY9Bc6+MIu6imSMc4dfZ/BYHqJY76lxfipg3WpRwbeIagen3wqXs5l+dH3icrNam8xO/BOYwLgABSrUO9CbJblI96iYhJa4tb1EvH0fjL5h50OmIdxlYpNdm3Vbo=

Best regards

Re: Encode Base64 doesn't return the correct value

Posted: Fri Jul 01, 2022 4:16 pm
by jonboy49
What's really needed is to see how you do the call to Scott's routine. The variable definitions etc. Repeating the same basic stuff you showed before doesn't help.

Re: Encode Base64 doesn't return the correct value

Posted: Fri Jul 01, 2022 4:29 pm
by hmauricio
The call :

base64_encode(%addr(signature)
: %len(%trimr(signature))
: %addr(hashg)
: %size(hashg));

Variables definition:
dcl-s signature char(512) ccsid(*hex);
Dcl-S hashg Char(2732) inz(' ');

The variable "Signature" is the result of the API
Qc3CalculateSignature(
StringHash :
%len(stringHash) :
'DATA0100' :
algorithmDescription :
'ALGD0400' :
keyDescription :
'KEYD0400' :
ANY_CRYPTO_SRV :
'' :
signature :
%size(signature) :
signatureLength :
stdError
);
Hope this helps.

Thankyou for your reply.

Re: Encode Base64 doesn't return the correct value

Posted: Fri Jul 01, 2022 4:46 pm
by hmauricio
For better undeestanding of what i'm doing, this is the full code.
//------------------------------------------------
CTL-Opt Option(*NoDebugIO:
*SRCSTMT);
CTL-Opt DFTACTGRP(*NO);
// CTL-Opt BNDDIR('QC2LE');
CTL-Opt BNDDIR('BASE64');
//------------------------------------------------
// E N T R Y P A R M S **
//-----------------------------------------------
DCL-PI *N; //hashgen_ap;
keyencrip char(32);
stringent char(250);
stringsai char(200);
END-PI;
//-----------------------------------------------
// The QUSEC Source Contains the Common Error Code Data Structure.
//-----------------------------------------------
/End-free
D/COPY QSYSINC/QRPGLESRC,QUSEC
D stdError DS qualified
D QUSEC likeDs(QUSEC)
D outError 1024A
/free
/copy BASE64_H
//-----------------------------------------------
dcl-c HASH_ALGORITHM_SHA1 2;
dcl-c HASH_ALGORITHM_SHA256 3;

dcl-c CRYPTO_ALGORITHM_RSA 50;

dcl-ds t_ALGD0400 len(12) qualified template;
publicKeyCipherAlgorithm int(10) pos(1);
pkaBlockFormat char(1) pos(5);
signingHashAlgorithm int(10) pos(9);
end-ds;

dcl-ds t_KEYD0400 len(56) qualified template;
keystoreFile char(10);
keystoreLibrary char(10);
recordLabel char(32);
end-ds;

dcl-pr Qc3CalculateSignature extproc(*dclcase);
inputData char(30000) options(*varsize) const;
inputDataLength int(10) const;
inputDataFormat char(8) const;
algorithmDescription char(32000) options(*varsize) const;
algorithmDescriptionFormat char(8) const;
keyDescription char(30000) options(*varsize) const;
keyDescriptionFormat char(8) const;
cryptoServiceProvider char(1) const;
cryptoDeviceName char(10) const;
signature char(512) ccsid(*hex) options(*varsize);
signatureLengthProvided int(10) const;
signatureLengthReturned int(10);
errorCode like(qusec);
end-pr;
//------------------------------------------------
// Stand alone fields definition
//------------------------------------------------
dcl-ds keyDescription likeds(t_KEYD0400);
dcl-ds algorithmDescription likeds(t_ALGD0400);
//dcl-ds qusec likeds(t_qusec) inz;
dcl-s signature char(512) ccsid(*hex);
dcl-s signatureLength int(10);
dcl-s StringHash varchar(65534) ccsid(*hex);
// dcl-s StringHash char(512) ccsid(*hex);
Dcl-S hashg Char(2732) inz(' '); //ccsid(819);
// Dcl-S hashg char(23096) inz(' ') ccsid(1208);
//
dcl-c ANY_CRYPTO_SRV Const('0');
dcl-c SWF_CRYPTO_SRV Const('1');
dcl-c HWD_CRYPTO_SRV Const('2');
dcl-s CRYPTO_SRV Char(10) inz(' ');
dcl-s outstring Char(50) inz(' ');
dcl-s wait Char(1) inz(' ');
dcl-s AsciiData char(750) ccsid(819);
//------------------------------------------------
// MAIN ROUTINE
//------------------------------------------------
Exsr CvtRecStr; // Converte string recebida no PARM
Exsr KeyDesDef; // Trata DS KeyDescription
Exsr AlgDesDef; // Trata DS AlgorithmDescription
Exsr CallAPI; // Chama API Qc2CalculateSignature
// Se existiu erro, mostra erro no ecra
F If stdError.qusec.qusbavl > 0;
| outstring = stdError.qusec.qusei;
X Else;
| Exsr CvtBase64; // Converte p/base64
E Endif;
*inlr = *on;
//------------------------------------------------
// CvtRecStr - Converte a string recebida de EBCDIC-ASCII-HEX
//------------------------------------------------
begsr CvtRecStr;
clear stringsai;
AsciiData = %Trim(stringent); // EBDCDIC -> ASCII
StringHash = %Trim(AsciiData); // ASCII -> HEX
Endsr;
//------------------------------------------------
// KeyDesDef - Trata campos DS KeyDescription
//------------------------------------------------
begsr KeyDesDef;
keyDescription = *allx'00';
keyDescription.keystoreFile = 'TESTE_KEY';
keyDescription.keystoreLibrary = '*LIBL';
keyDescription.recordLabel = %trim(keyencrip);
Endsr;
//------------------------------------------------
// AlgDesDef - Trata campos DS AlgorithmDescription
//------------------------------------------------
begsr AlgDesDef;
algorithmDescription = *allx'00';
algorithmDescription.publicKeyCipherAlgorithm = CRYPTO_ALGORITHM_RSA;
algorithmDescription.pkaBlockFormat = '1';
algorithmDescription.signingHashAlgorithm = HASH_ALGORITHM_SHA1;
Endsr;
//------------------------------------------------
// CallAPI - Chama API Qc2CalculateSignature
//------------------------------------------------
begsr CallAPI;
Qc3CalculateSignature(
StringHash :
%len(stringHash) :
'DATA0100' :
algorithmDescription :
'ALGD0400' :
keyDescription :
'KEYD0400' :
ANY_CRYPTO_SRV :
'' :
signature :
%size(signature) :
signatureLength :
stdError
);
Endsr;
//------------------------------------------------
// CvtBase64 - Converte signature para Base64
//------------------------------------------------
begsr CvtBase64;
Clear hashg;
base64_encode(%addr(signature)
: %len(%trimr(signature))
: %addr(hashg)
: %size(hashg));
stringsai = %Trim(hashg); // Parametro saida
Endsr;
//------------------------------------------------
/End-free


Best regards

Re: Encode Base64 doesn't return the correct value

Posted: Fri Jul 01, 2022 5:02 pm
by Scott Klement
This is the problem:

%len(%trimr(signature))

You can't use %trimr on a binary field. If the number x'40' happens to be at the end, it will remove it -- because it considers x'40' a blank -- which is exactly the difference between the two base64 string you posted at the start of this thread.

You have to pass the actual length of the signature, not calculate it by trimming blanks and seeing how long the result is.

Re: Encode Base64 doesn't return the correct value

Posted: Fri Jul 01, 2022 5:04 pm
by hmauricio
Thanks Scott,
i'll try that and get back to you.


Best regards

Re: Encode Base64 doesn't return the correct value

Posted: Fri Jul 01, 2022 5:15 pm
by hmauricio
Well Scott, i tried as you said, remove the %Trim, but the problem now is that now we've the blanks of the signature field on the encoded field as you can se, and besides that the encoded isnt correct either, the last characters should be UA= and not UB and then followed by all the blanks .

Encoded String:
CIqVstFuI4a44OYFcVIR7nhf+SzlOVFJBOzu6BW7c/DX3Fjyprns57Iu1/RTrGnvVcrEc4bO724IIYNdHIVFuR1p8296505vZhN3rXc879KSLDZFH8UnrWtdt2Z0CuDwtPK0aZfElM4JkGCimH6xS3tGVVfvPhYj7siE3rnaoUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEA=

Correct String:
CIqVstFuI4a44OYFcVIR7nhf+SzlOVFJBOzu6BW7c/DX3Fjyprns57Iu1/RTrGnvVcrEc4bO724IIYNdHIVFuR1p8296505vZhN3rXc879KSLDZFH8UnrWtdt2Z0CuDwtPK0aZfElM4JkGCimH6xS3tGVVfvPhYj7siE3rnaoUA=

Actual call:
base64_encode(%addr(signature)
: %len(signature)
: %addr(hashg)
: %size(hashg));

Helder

Re: Encode Base64 doesn't return the correct value

Posted: Fri Jul 01, 2022 5:36 pm
by jonboy49
The signature length is being returned to by Qc3CalculateSignature. Any reason you cannot use that ?