Subscribe for automatic updates: RSS icon RSS

Login icon Sign in for full access | Help icon Help
Advanced search

Pages: [1]
  Reply  |  Print  
Author Topic: Google Web Service URL Signing with HMAC-SHA1  (Read 12856 times)
Tim B.
Posts: 67


« on: November 20, 2015, 11:48:08 am »

Hi

Back again after a long time...

I have a 4GL program which interfaces to Google Maps Web Service APIs (com.HTTPRequest.Create etc).  All works very well, so far.  However, we're trying to move off the free version (has low usage limits) to the business version.  To do this The URL need to be encoded and signed using HMAC-SHA1 and a key that Google provide.  Google kindly provide examples in Python, Java & C# (and I've also found something for PHP), but not in Genero for some reason.... :)

It looks like the Genero xml library handles hmac-sha1, but I'm a bit lost with it.  In Python this is the code to do this:-

decoded_key = base64.urlsafe_b64decode([Google Crypto Key])
signature = hmac.new(decoded_key, [URL path], hashlib.sha1)
encoded_signature = base64.urlsafe_b64encode(signature.digest())

Lifted from here:-
https://developers.google.com/maps/documentation/business/image/auth?hl=en

Are there equivalent functions in Genero?

MTIA

Tim
Frank G.
Four Js
Posts: 48


« Reply #1 on: November 20, 2015, 05:01:45 pm »

Hi TIM,

 You may try something like following :

IMPORT XML

CONSTANT KEY_IN_BASE64_URL_SAFE = "Google Crypto Key"
CONSTANT URL_TO_SIGN = "XXX"

MAIN
  DEFINE key xml.CryptoKey
  DEFINE ret  STRING
  LET key = xml.CryptoKey.Create("http://www.w3.org/2000/09/xmldsig#hmac-sha1") 
  CALL key.loadFromString(Base64Url2Base64(KEY_IN_BASE64_URL_SAFE))
  LET ret = xml.Signature.signString(key,URL_TO_SIGN)
  DISPLAY "Signature in base64 :",Base642Base64Url(ret)
END MAIN

# Convert Base64 safe URL to Base64 format
FUNCTION Base64Url2Base64(s)
  DEFINE  s   STRING
  DEFINE  buf base.stringBuffer
  LET buf = base.StringBuffer.create()
  CALL buf.append(s)
  CALL buf.replace("-","+",0)
  CALL buf.replace("_","/",0)
  CASE (s.getLength() MOD 4)
    WHEN 1
      RETURN NULL # ERROR (Illegal base64url string!)
    WHEN 2
      CALL buf.append("==")
    WHEN 3
      CALL buf.append("=")     
  END CASE
  RETURN buf.toString()
END FUNCTION 

# Convert Base64 to Base64 safe url format
FUNCTION Base642Base64Url(s)
  DEFINE  s   STRING
  DEFINE  buf base.stringBuffer
  LET buf = base.StringBuffer.create()
  CALL buf.append(s)
  CALL buf.replace("+","-",0)
  CALL buf.replace("/","_",0)
  CALL buf.replace("=",NULL,0)
  RETURN buf.toString()
END FUNCTION

Notice that Genero APis loadFromString() and signString() work with base64 and not url safe base64. Therefore you need to call Base64Url2Base64() and Base642Base64Url()

Regards,
Frank

Tim B.
Posts: 67


« Reply #2 on: November 20, 2015, 05:28:27 pm »

Thank you very much.  Unfortunately xml.Signature.signString method is new in 2.50, and we're not on that version.  We are looking at an upgrade though, so we should be able to use this then.

I have a temporary workaround by creating a PHP web service and calling that to do the signing.

Tim
Reuben B.
Four Js
Posts: 1047


« Reply #3 on: November 22, 2015, 10:08:17 pm »

Tim,

I'll just make sure you are aware you can run multiple Genero versions on the same server.  So instead of having a PHP Web Service, you could have a Genero 2.50 Web Service running that your older programs could call.

Reuben

Product Consultant (Asia Pacific)
Developer Relations Manager (Worldwide)
Author of https://4js.com/ask-reuben
Contributor to https://github.com/FourjsGenero
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines