简体   繁体   中英

How to generate signature using SHA-1 HMAC for google map in ruby

I am trying to generate signature using SHA-1 HMAC in ruby for google maps calls. I have got a python's code from the internet which I am trying to copy into ruby. Following is phython's code

import urllib.parse
import base64
import hashlib
import hmac 
GOOGLEAPIS_URL = 'http://maps.googleapis.com'
STREETVIEW_ENDPOINT = '/maps/api/streetview'
encodedParams = urllib.parse.urlencode({'size':'50x50','location':'42.35878993272469,-71.05793081223965','sensor':'false','client':'gme-securealert'});
privateKey = 'Encoded_Key' # e.g XEL-B9Zs3lRLajIXkD-bqTYix20=
decodedKey = base64.urlsafe_b64decode(privateKey)
urlToSign = STREETVIEW_ENDPOINT + '?' + encodedParams
print(urlToSign)
signature = hmac.new(decodedKey, urlToSign.encode('utf-8') , hashlib.sha1)
encodedSignature = base64.urlsafe_b64encode(signature.digest())
print(encodedSignature

)

that generates OI2DXDLq7Qd790Lokaxgqtis_pE= signature.

Following is the Ruby code that I am trying to achieve same signature with.

GOOGLE_APIS_URL= "http://maps.googleapis.com"      
key = Encoded_Key # e.g XEL-B9Zs3lRLajIXkD-bqTYix20=
data ='/maps/api/streetview?size=50x50&sensor=false&client=gme-securealert&location=42.35878993272469,-71.05793081223965'

data_array = data.split("?")
STREET_VIEW_ENDPOINT = data_array[0]
query_string = data_array[1]

encoded_query_string =  URI.escape(query_string) # to encode parameters only
decoded_key = Base64.decode64(key) # to decode the key

data = STREET_VIEW_ENDPOINT << '?' << encoded_query_string
#p "DATA #{data}"
#data = Base64.decode64(data)
#puts "data #{data}"
digest = OpenSSL::Digest.new('sha1')
p OpenSSL::HMAC.digest(digest, decoded_key, data)
hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, decoded_key, data))
p hmac

but this seems to be not working for me. Please guide.

You can create the hash for request parameters and use URI.encode_www_form for encoding parameters. Use Base64.urlsafe_decode64 and Base64.urlsafe_encode64 instead of Base64.decode64 and Base64.encode64. In my case, I have used reverse geocoding api. You will need to ammend the parameters and REVERSE_GEOCODING_ENDPOINT_JSON. Hope this will help you. Please let me know if you have any queries.

GOOGLE_MAPS_API_CLIENT_ID = 'gme-xyz'
GOOGLE_MAPS_API_CRYPTO_KEY = 'private_key'
GOOGLEAPIS_HTTP_URL = 'http://maps.googleapis.com'
REVERSE_GEOCODING_ENDPOINT_JSON = '/maps/api/geocode/json'

str_latlng = lat.to_s + ',' + lon.to_s
encoded_params = URI.encode_www_form({'latlng' => str_latlng,
                                      'client' => GOOGLE_MAPS_API_CLIENT_ID})
decoded_key = Base64.urlsafe_decode64(GOOGLE_MAPS_API_CRYPTO_KEY)
url_to_sign = REVERSE_GEOCODING_ENDPOINT_JSON + '?' + encoded_params
digest = OpenSSL::Digest.new('sha1')
signature = OpenSSL::HMAC.digest(digest, decoded_key, url_to_sign)
encoded_signature = Base64.urlsafe_encode64(signature)
signed_url = GOOGLEAPIS_HTTP_URL + REVERSE_GEOCODING_ENDPOINT_JSON + '?' + encoded_params + '&signature='+encoded_signature

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM