无法使用Salesforce Crypto Class为Google Maps API生成HMac

时间:2012-12-14 13:09:07

标签: google-maps-api-3 salesforce apex-code hmacsha1

我的公司最近注册了Google Maps API for business。

要使用API​​,我需要生成HMacSHA1签名,并将其添加到我的HTTP请求中。不幸的是,不知何故,我无法生成正确的签名。

为了测试,我使用谷歌提供的值来确保算法正常工作,我得到了正确的结果。这是代码:

string url = 'maps/api/geocode/json?address=New+York&sensor=false&client=clientID';
string privateKey = 'vNIXE0xscrmjlyV-12Nj_BvUPaw=';
privateKey = privateKey.replace('-', '+');
privateKey = privateKey.replace('_', '/');

//Blob privateKeyBlob = EncodingUtil.base64Decode(privateKey);
Blob privateKeyBlob = Blob.valueOf(privateKey);
Blob urlBlob = Blob.valueOf(url);
Blob signatureBlob = Crypto.generateMac('HMacSHA1', urlBlob, privateKeyBlob);

String signature =EncodingUtil.urlEncode(EncodingUtil.base64Encode(signatureBlob), 'UTF-8');
signature = signature.replace('+', '-');
signature = signature.replace('/', '_');

system.debug('signature is ' +signature);

生成的签名应为:KrU1TzVQM7Ur0i8i7K3huiw3MsA =

以下是Google文档的链接,您也可以在其中找到相同的示例:https://developers.google.com/maps/documentation/business/webservices

几点需要注意: 1.我使用了API文档中提供的示例Python脚本,它给出了正确的结果。 2.我认为问题是,API Documentation说我们应该解码privateKey然后将它提供给函数。虽然Crypto Class的文档说“privateKey的值不需要以解码的形式。”。我尝试了两种方法,无论是否解码,仍然没有结果。 3.对于Google API,一切都必须是UTF-8编码;我不知道这是否就像Encoding.Util解码那样。

我尝试了很多组合,但找不到解决方案。任何帮助都将受到高度赞赏。

谢谢, ANKIT

2 个答案:

答案 0 :(得分:5)

您需要签署完整路径和查询。您的字符串网址缺少前导斜杠(/).

此外,不要害怕与Google打开支持案例进行此类查询。

答案 1 :(得分:0)

我们已经使用了代码,但是它有一些缺陷,对于打算使用此代码的人来说,实际代码将是:

string url = '/maps/api/geocode/json?address=New+York&sensor=false&client=clientID';
string privateKey = 'vNIXE0xscrmjlyV-12Nj_BvUPaw=';
privateKey = privateKey.replace('-', '+');
privateKey = privateKey.replace('_', '/');

Blob privateKeyBlob = EncodingUtil.base64Decode(privateKey);
Blob urlBlob = Blob.valueOf(url);
Blob signatureBlob = Crypto.generateMac('hmacSHA1', urlBlob, privateKeyBlob);

String signature = EncodingUtil.base64Encode(signatureBlob);

signature = signature.replace('+', '-');
signature = signature.replace('/', '_');

system.debug('*** Signature: ' + signature);