Construct URL-Friendly Base64 Strings

Wednesday, 22 June 2022 · 3 messages
EK
Eliot Kimber22 Jun 2022 18:48 #
I’m trying to replicate a call to a remote REST API that uses hmac encoding to construct an authentication string. I’m working from existing Python code that does the same thing. What I’m seeing is that the crypto:hmac() function can return Base64 strings that include characters that must be escaped in URIs, i.e.: mTA76dRZkiCf84WUKM/PWySydamj3dMZ6Tm26s9QGNI (Note the “/”) Python’s base64 support includes the method urlsafe_b64encode(), which avoids the characters “+” and “/”. Unfortunately the handler of the API call fails if I escape the “/” or “+”—I’m not sure why. So I need to construct the same URI-friendly base64 string that the Python method is generating. I don’t see an obvious way to do this with the BaseX conversion package. Is there a way short of implementing my own Base64 encoding algorithm to get a URI-friendly base64 string? I’m using 9.6.4 at the moment but could upgrade if necessary. Thanks, E. _____________________________________________ Eliot Kimber Sr Staff Content Engineer O: 512 554 9368 M: 512 554 9368 servicenow.com<https://www.servicenow.com> LinkedIn<https://www.linkedin.com/company/servicenow> | Twitter<https://twitter.com/servicenow> | YouTube<https://www.youtube.com/user/servicenowinc> | Facebook<https://www.facebook.com/servicenow>
EK
Eliot Kimberin reply to Liam R. E. Quin, 22 Jun 2022, 21:5622 Jun 2022 20:20 #
“/” needs to be escaped in the context of a parameter, I think, but in any case I found the answer on the internet: URL-friendly base64 uses “-_” instead of “+/”, so the solution is to simply translate “+/” to “-_”:
let $authCode as xs:string := crypto:hmac($toBeEncrypted, $secret, 'sha256') ! string(.) ! replace(., '=', '')
let $escapedAuthCode as xs:string := translate($authCode, '+/', '-_')
And it works a treat. The Wikipedia page for base64 gave me the clue I needed (https://en.wikipedia.org/wiki/Base64). (and of course I could have made this code much more compact—this is just my test bed scratch code). Cheers, E. _____________________________________________ Eliot Kimber Sr Staff Content Engineer O: 512 554 9368 M: 512 554 9368 servicenow.com<https://www.servicenow.com> LinkedIn<https://www.linkedin.com/company/servicenow> | Twitter<https://twitter.com/servicenow> | YouTube<https://www.youtube.com/user/servicenowinc> | Facebook<https://www.facebook.com/servicenow>
Quoted text · Liam R. E. Quin · 29 lines
From: Liam R. E. Quin <liam at fromoldbooks.org> Date: Wednesday, June 22, 2022 at 12:56 PM To: Eliot Kimber <eliot.kimber at servicenow.com>, basex-talk at mailman.uni-konstanz.de <basex-talk at mailman.uni-konstanz.de> Subject: Re: [basex-talk] Construct URL-Friendly Base64 Strings [External Email] On Wed, 2022-06-22 at 16:48 +0000, Eliot Kimber wrote: > I’m trying to replicate a call to a remote REST API that uses hmac > encoding to construct an authentication string. I’m working from > existing Python code that does the same thing. > > What I’m seeing is that the crypto:hmac() function can return Base64 > strings that include characters that must be escaped in URIs, i.e.: > > mTA76dRZkiCf84WUKM/PWySydamj3dMZ6Tm26s9QGNI > > (Note the “/”) I think that / does not need to be escaped in a URI as otherwise things like amazon.com/freestuff/books wouldn't be allowed. You do need to escape = however, as it is used to represent a space, and you MAY need to escape / depending on the receiving end. replace($uri, '[+]', '%2B') would presumably be sufficient for plus, and 2F for / if you need that escaped too. liam -- Liam Quin, https://urldefense.com/v3/__https://www.delightfulcomputing.com/__;!!N4vogdjhuJM!B42RLgHq3VQQgGPYxAYTw-XVyMLgPFuGBaN95-iDGQdbW62INOxEkAdRhiRt_pOu1YSXSdNSwxudfSL2XU0rQx8$<https://urldefense.com/v3/__https:/www.delightfulcomputing.com/__;!!N4vogdjhuJM!B42RLgHq3VQQgGPYxAYTw-XVyMLgPFuGBaN95-iDGQdbW62INOxEkAdRhiRt_pOu1YSXSdNSwxudfSL2XU0rQx8$> Available for XML/Document/Information Architecture/XSLT/ XSL/XQuery/Web/Text Processing/A11Y training, work & consulting. Barefoot Web-slave, antique illustrations: https://urldefense.com/v3/__http://www.fromoldbooks.org__;!!N4vogdjhuJM!B42RLgHq3VQQgGPYxAYTw-XVyMLgPFuGBaN95-iDGQdbW62INOxEkAdRhiRt_pOu1YSXSdNSwxudfSL2wlRRdwE$<https://urldefense.com/v3/__http:/www.fromoldbooks.org__;!!N4vogdjhuJM!B42RLgHq3VQQgGPYxAYTw-XVyMLgPFuGBaN95-iDGQdbW62INOxEkAdRhiRt_pOu1YSXSdNSwxudfSL2wlRRdwE$>
LQ
Liam R. E. Quinin reply to Eliot Kimber, 22 Jun 2022, 18:4822 Jun 2022 21:56 #
Quoted text · Eliot Kimber · 11 lines
On Wed, 2022-06-22 at 16:48 +0000, Eliot Kimber wrote: > I’m trying to replicate a call to a remote REST API that uses hmac > encoding to construct an authentication string. I’m working from > existing Python code that does the same thing. > > What I’m seeing is that the crypto:hmac() function can return Base64 > strings that include characters that must be escaped in URIs, i.e.: > > mTA76dRZkiCf84WUKM/PWySydamj3dMZ6Tm26s9QGNI > > (Note the “/”)
I think that / does not need to be escaped in a URI as otherwise things like amazon.com/freestuff/books wouldn't be allowed. You do need to escape = however, as it is used to represent a space, and you MAY need to escape / depending on the receiving end.
  replace($uri, '[+]', '%2B')
would presumably be sufficient for plus, and 2F for / if you need that escaped too. liam
-- Liam Quin, https://www.delightfulcomputing.com/ Available for XML/Document/Information Architecture/XSLT/ XSL/XQuery/Web/Text Processing/A11Y training, work & consulting. Barefoot Web-slave, antique illustrations: http://www.fromoldbooks.org

⚡Generated with XQuery