Good Morning.Please can anyone tell me if there is a difference between Progress's BASE64-ENCODE function and PHP's base_encode function?Or BASE-DECODE of Progress and PHP_base_decode?Thanks.
E.g. Encoding the string "SomeStringOfText:1234"PHP (encodeBase64): U29tZVN0cmluZ09mVGV4dDoxMjM0Progress (BASE64-ENCODE): U29tZVN0cmluZ09mVGV4dDoxMjM0AA==
The "AA==" on the end of the Progress string is reasonably consistent but I couldn’t find any docs or logged issues to explain the difference.
Rather than risking it on a production system we went with a call to PHP to do the encoding.
The AA== stuff has undoubtedly to do with how string are terminated which it itself is not that interesting. If I decode your PHP encoded string in OpenEdge I get the exact same string as you inputted in PHP. The other way around works perfectly as well.
I'm 100% certain if you have the exact same byte sequence as input for your encode functions the results will be the same.
def var mptr as memptr.
mptr = ( base64-decode( "AA==" ) ).
message get-size( mptr ) get-byte( mptr, 1 ).
So if you are ending with AA== then you are probably sizing your strings 1 byte too large resulting in a 0 terminator.
when you do:
SET-SIZE(mptr) = LENGTH(inputString) + 1.
PUT-STRING(mptr, 1) = inputString.
You have add 1 to the length or the string will not fit and then it's zero terminated. That's where the "AA==" is coming from. Instead of adding 1 to the size you can restrict the amount of bytes written to the memptr by:
SET-SIZE(mptr) = LENGTH(inputString).
PUT-STRING(mptr, 1, LENGTH(inputString, "RAW")) = inputString.
Then you get the same output as Java, PHP, etc...
note: the "RAW" parameter with the length function should be used when using multi-byte codepages (i.e. utf-8).
And of course the second SET-SIZE has to be LENGTH(inputString, "RAW") as well.
So, no need to use PHP. I fail to see why anyone would consider using PHP in 2018 anyway :-)
My template is made in PHP, which I did in Progress 4GL is returning a signature other than PHP.
My code is:
DEF VAR apiSecret AS CHAR NO-UNDO.
DEF VAR stringtosign AS CHAR NO-UNDO.
DEF VAR secretKey AS MEMPTR NO-UNDO.
DEF VAR c_signature AS LONGCHAR NO-UNDO.
ASSIGN apiid = "b4t5yug1q6du"
apisecret = "UJe7NicGijgkTSKByC+/B86NDafeGYGDXsxJKiLKH8LE9ni5whmTdof6QgR6vGXonn0htVOLsRXRcpEg4QPWSA==".
ASSIGN dat_ref = 'x-csod-date:2018-06-28T13:37:35.000'.
ASSIGN httpMethod = 'POST'
apiKey = 'x-csod-api-key:' + apiId
httpUrl = '/services/api/sts/session'.
stringToSign = httpMethod + "\n" + apiKey + "\n" + dat_ref + "\n" + httpUrl.
ASSIGN secretKey = base64-DECODE(apiSecret).
ASSIGN c_signature = BASE64-ENCODE (MESSAGE-DIGEST('SHA-512', stringToSign, secretKey)).
The result of the c_signature variable is different if I put the same code in PHP.
Your \n's look suspicious to me - they will result in line feeds (chr 10) on Linux and a literal \n on windows. If you use ~n it will be a line feed on both.
My friend, I put this "signature" in POSTMAN, and sent, the same error occurs, using the "\ n".
In ABL you get a null-terminated string.
In the HTTP Client we have code that has to deal woith this. See github.com/.../BasicAuthenticationFilter.cls for detail.
Definition: The moment when you realise the vast dimensions of the blind spot previously applied when examining an issue.
Have you tried this?
stringToSign = httpMethod + CHR(10) + apiKey + CHR(10) + dat_ref + CHR(10) + httpUrl.
Peter Judge : any particular reason why you don't do
set-size(mShortCredentials) = iLength.
put-bytes(mShortCredentials, 1, iLength) = cCredentials.
Yes, I tried and the answer keeps returning differently, between PHP and Progress.