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
“/” 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
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
Written for BaseX 9.7. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery