Visit our Google Group
Discuss with other developers, get support and leave us feedback.

Authentication

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.

The Authentication Process

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.

  1. Create a request

    In the case of send_message, your request consists of:

    Zeep Media
  2. Create an HMAC-SHA1 signature

    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]

    Zeep Media
  3. Send the signed HTTP request to Zeepmobile.com

    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.

    Zeep Media

Generating the Authorization Header

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]

API Key

Your API Key for each of your applications can be found in your Account section once you have added an application.

HMAC+SHA1 Encoded Canonical

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.

"Hmac Sha1" Example in Ruby:

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

"Hmac Sha1" Example in Python:

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()

"Hmac Sha1" Example in Java:

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();
    }
  }
}

Putting it all Together

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