Authentication is used to validate your identity. Authentication ensures that someone else can't reach your users without your permission. Security always relies on a secret. For Zeep Mobile, this secret is your Secret Key. It should not be shared outside of your organization. You enable authentication of your requests by including a signature that is calculated using your Secret Key.
Following are the general steps for authenticating requests to Zeep Mobile. It is assumed you have already created an API Key and have your Secret Key.
In the case of send_message, your request consists of:
This signature is required to determine that it is actually your app sending the request. Calculate a keyed-hash message authentication code (HMAC+SHA1) signature using your Secret Key. More about these signatuers. [http://wikipedia.org]
Include the signature and your API Key in the request, and then send the request to Zeep. Zeep performs the same calculations with your Secret Key retrieved from our database verify your identity.
Header based authentication is achieved by setting a special Authorization header whose value is formatted like so:
Authorization: Zeep [API Key]:[HMAC+SHA1 Encoded Canonical]
Your API Key for each of your applications can be found in your Account section once you have added an application.
The "canonical string" is computed by collecting the value of the Date header, your API Key and the current request parameters into a string. That canonical string is then encrypted with the Secret Key assigned by Zeep. The resulting encrypted canonical string is then base 64 encoded.
Your Secret Key for each of your applications can also be found in your Account section once you have added an application.
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 |
#!/usr/bin/env ruby -wKU
# Created by Simon Wex (simon@zeepmobile.com) on 2008-07-12
# Copyright (c) 2008. All rights reserved.
# Released under MIT License
require 'openssl'
require 'base64'
require 'time'
require 'cgi'
API_KEY = 'cef7a046258082993759bade995b3ae8'
SECRET_ACCESS_KEY = '19c87eb3e3a28404e7ea8197d4401540'
# (ex. Sat, 12 Jul 2008 09:04:28 GMT)
http_date = Time.now.httpdate
parameters = "user_id=1234&body=#{CGI.escape('Art thou not Romeo, and a Montague?')}"
# => "user_id=1234&body=Art+thou+not+Romeo%2C+and+a+Montague%3F"
canonical_string = "#{API_KEY}#{http_date}#{parameters}"
# => "cef7a046258082993759bade995b3ae8Sat, 12 Jul 2008 09:04:55 GMTuser_id=1234&body=Art+thou+not+Romeo%2C+and+a+Montague%3F"
digest = OpenSSL::Digest::Digest.new('sha1')
b64_mac = Base64.encode64(OpenSSL::HMAC.digest(digest, SECRET_ACCESS_KEY, canonical_string)).strip
authentication = "Zeep #{API_KEY}:#{b64_mac}"
puts authentication
|
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 |
#!/usr/bin/env python
# Created by Simon Wex (simon@zeepmobile.com) on 2008-07-12
# Copyright (c) 2008. All rights reserved.
# Released under MIT License
import base64
import hmac
import sha
import time
SECRET_ACCESS_KEY = '19c87eb3e3a28404e7ea8197d4401540'
kv = {'API_KEY': 'cef7a046258082993759bade995b3ae8',
'Body': 'The brown fox jumped over the lazy dog.',
'Version': '2008-07-18',
'SignatureVersion': '1',
'Timestamp': time.strftime('%a, %d %b %Y %H:%M:%S GMT',time.gmtime())
}
sig = hmac.new(SECRET_ACCESS_KEY, digestmod=sha)
items = kv.items()
# Sort the keys
items.sort()
for key, value in items:
sig.update(key)
sig.update(value)
print base64.encodestring(sig.digest()).strip()
|
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 |
// Created by Simon Wex (simon@zeepmobile.com) on 2008-07-12
// Copyright (c) 2008. All rights reserved.
// Released under MIT License
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
public class HmacSha1 {
public static final String API_KEY = "cef7a046258082993759bade995b3ae8";
public static final String SECRET_ACCESS_KEY = "19c87eb3e3a28404e7ea8197d4401540";
public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";
/**
* @param args
*/
public static void main(String[] args) {
try {
SimpleDateFormat httpDateFormat = new SimpleDateFormat();
httpDateFormat.applyPattern(PATTERN_RFC1123);
httpDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
String httpDate = httpDateFormat.format(new Date());
// (ex. Sat, 12 Jul 2008 09:04:28 GMT) http_date = Time.now.httpdate
String body = URLEncoder.encode("Art thou not Romeo, and a Montague?", "UTF-8");
//user_id=1234&body=Art+thou+not+Romeo%2C+and+a+Montague%3F
String parameters = "user_id=1234&body=" + body;
String canonicalString = API_KEY + httpDate + parameters;
System.out.println(canonicalString);
Mac mac = Mac.getInstance("HmacSHA1");
byte[] keyBytes = SECRET_ACCESS_KEY.getBytes("UTF8");
SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1");
mac.init(signingKey);
byte[] signBytes = mac.doFinal(canonicalString.getBytes("UTF8"));
String b64Mac = Base64.encode(signBytes);
String authentication = "Zeep " + API_KEY + ":" + b64Mac;
System.out.println(authentication);
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (InvalidKeyException e) {
e.printStackTrace();
}
}
} |
Here is an example of an Authorization header included in an HTTP Post:
POST /api/send_message HTTP/1.1 Host: zeepmobile.com Authorization: Zeep cef7a046258082993759bade995b3ae8:XGPPx8+Me8RBoEUTPO6LSiSLDn4= Date: Tue, 06 Jan 2009 01:13:16 GMT Content-Type: application/x-www-form-urlencoded Content-Length: 70 user_id=1234&body=Art+thou+not+Romeo%2C+and+a+Montague%3F