PHP and Progress 4GL - Forum - OpenEdge Development - Progress Community
 Forum

PHP and Progress 4GL

This question has suggested answer(s)

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.

All Replies
  • There is a difference.  Equivalent PHP, Javascript and Java functions all give the same result, Progress gives a different result.

    E.g. Encoding the string "SomeStringOfText:1234"
    PHP (encodeBase64): U29tZVN0cmluZ09mVGV4dDoxMjM0
    Progress (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 :-)

    (flame alert).

  • 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.

    Why ?

  • 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.

    abldojo.services.progress.com:443/

    results in

    pMOyRFxJMLEaXWb5kP9haQFgI+ZBpG+4MurIDMWMgXhpu2Ge2t4OYUkO/pwbiG3lDP8LiTphzP1vVTIWiEDd9w==

  • 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.

  • Doh!

    Definition: The moment when you realise the vast dimensions of the blind spot previously applied when examining an issue.

    Thank you.

  • Have you tried this?

    stringToSign = httpMethod + CHR(10) + apiKey + CHR(10) + dat_ref + CHR(10) + httpUrl.

  • : any particular reason why you don't do

    set-size(mShortCredentials) = iLength.

    put-bytes(mShortCredentials, 1, iLength) = cCredentials.

    straight away?

  • Yes, I tried and the answer keeps returning differently, between PHP and Progress.