How to Generate OAuth Signature for twitter in core JAVA

Twitter.com provides an API for developers to interact with twitter data in their own application,products and services. the twitter API.
is basically a webservice. A developer has to log in or sing up with the twitter platform,register for an API key for his/her application
and use that key to drive interaction on behalf of an authenticated user. visit twitter API Documentation for lmore information on how to utilize the offered service.

Twitter uses OAuth 1.0 Protocol to authenticate API calls of third party applications. OAuth Authentication in twitter API describe how the authentication flow should be.

In this post i’m going to describe how to generate the oauth_signature for twitter request according to The OAuth 1.0 Protocol Section 3.4 Signature in Core Java(mainly for JAVA 1.4 or higher).
The oauth_signature parameter is generated by applying a signing algorithm on all the other request parameters and two secret values.This signature is used for below purposes.

  1. To verify the request has not been modified in transit.
  2. To verify the application sending the request.
  3. To verify that the application is authorized to interact with the resource owner’s account.

Here are the steps of oauth_signature generation algorithm for twitter.

Step 1: Collecting the request method and URL
The first step is to determine the HTTP method and Base URL of the request. For twitter, the HTTP method will either be GET or POST.
The base URL is construced by removing any query string or hash parameters from the URL to which the request is directed. For example consider the following URL which is used as a GET request.

https://api.twitter.com/1.1/lists/statuses.json?slug=teams&owner_screen_name=MLS

The HTTP method and the base URL is as follows.

The HTTP method = GET  
   
The Base URL = https://api.twitter.com/1.1/lists/statuses.json
Step 2: Collecting parameters
The next step is to collect all of the parameters included in the request. There are two such locations for these additional parameters – the URL (as part of the query string) and the request body. Consider the following example.
 GET /lists/statuses.json?slug=teams&owner_screen_name=MLS  
 Host : https://api.twitter.com  
 Authorization: OAuth   
 oauth_consumer_key="fOJaKhsm1lHH9GoAoaH1LNRik",  
 oauth_token="8d3221fb072f31b5ef1b3bcfc5d8a27a",  
 oauth_signature_method="HMAC-SHA1",  
 oauth_timestamp="1270248088",  
 oauth_nonce="515379974",  
 oauth_signature="Gf5NUq1Pvg3DrtxHJyVaMXq4Foo%3D"  
 oauth_version="1.0"   

Here are the parameters and corresponding values collected from this request (oauth_signature parameter is not considered here). You should collect the raw values (before do the URL encoding).

 

Parameter Value
slug terms
owner_screen_name MLS
oauth_consumer_key fOJaKhsm1lHH9GoAoaH1LNRik
oauth_token 8d3221fb072f31b5ef1b3bcfc5d8a27a
oauth_signature_method HMAC-SHA1
oauth_timestamp 1270248088
oauth_nonce 515379974
oauth_version 1.0

These values need to be encoded into a single string in following specific way as below.

  1. Percent encode every key and value that will be signed.
  2. Sort the list of parameters alphabetically by encoded key. In case of two parameters with the same encoded key, continue sorting based on value.
  3. For each key/value pair:
    1. Append the encoded key to the output string.
    2. Append the ‘=’ character to the output string.
    3. Append the encoded value to the output string.
    4. If there are more key/value pairs remaining, append a ‘&’ character to the output string.

Following Java method can be used to Percent encoding.

 

import java.net.URLEncoder;  
  ....  
  
   /**
    * percentage encoding
    *
    * @return A encoded string
    */
 private String encode(String value) {  
     String encoded = "";  
     try {  
       encoded = URLEncoder.encode(value, "UTF-8");  
     } catch (Exception e) {  
       e.printStackTrace();  
     }  
      String sb = "";  
     char focus;  
     for (int i = 0; i < encoded.length(); i++) {  
       focus = encoded.charAt(i);  
       if (focus == '*') {  
         sb += "%2A"; 
       } else if (focus == '+') {  
         sb += "%20";
       } else if (focus == '%' && i + 1 < encoded.length()  
           && encoded.charAt(i + 1) == '7' && encoded.charAt(i + 2) == 'E') {  
         sb += '~';
         i += 2;  
       } else {  
         sb += focus;
       }  
     }  
     return sb.toString();  
   }  

The generated parameter string for the above example is like below.

date=2014%2F03%2F19&oauth_consumer_key=fitbit-example-client-application&oauth_nonce=515379974&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1270248088&oauth_token=8d3221fb072f31b5ef1b3bcfc5d8a27a&oauth_version=1.0&user_id=1234    

Step 3: Creating the signature base string

According to the OAuth specification, the signature base string is constructed by concatenating together, in order, the following elements we prepared in above steps;

  • HTTP method
  • Base URL
  • Parameter string

These values need to be encoded into a single string in following specific way.

  • Convert the HTTP Method to uppercase and set the output string equal to this value.
  • Append the ‘&’ character to the output string.
  • Percent encode the URL and append it to the output string.
  • Append the ‘&’ character to the output string.
  • Percent encode the parameter string and append it to the output string.

Do not forget to percent encode the parameter string. The resulting signature base string will have exactly 2 ampersand ‘&’ characters. The percent ‘%’ characters in the parameter string should be encoded as %25 in the signature base string.

This is the resulting signature base string for example we are discussing.
GET&https%3A%2F%2Fwww.example.com%2Fuser%2Factivities&date%3D2014%252F03%252F19%26oauth_consumer_key%3Dfitbit-example-client-application%26oauth_nonce%3D515379974%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1270248088%26oauth_token%3D8d3221fb072f31b5ef1b3bcfc5d8a27a%26oauth_version%3D1.0%26user_id%3D1234     
Step 4: Creating the signing key
Signing key is used to generated the signature string from signature base string which we discussed in step 3.
To create the signing key, you need have following secret values.
  • Consumer Secret : The client secret should obtain upon at the registration of your application with twitter.
  • OAuth token secret : The token  secret should obtain upon at the registration of your application with twitter.

The signing key is simply the percent encoded consumer secret, followed by anampersand character ‘&’, followed by the percent encoded token secret.
If the token secret is not yet known the signing key should consist of the percent encoded consumer secret followed by an ampersand character ‘&’.

 

Step 5: Calculating the signature
Final step is the generating signature. According to Fitbit documentation, signature generation method could be either of HMAC-SHA1, RSA-SHA1, PLAINTEXT. I have only tried HMAC-SHA1 and this is how I did it.
  1. Pass signature base string created from Step 3 and signing key from Step 4 to the HMAC-SHA1 hashing algorithm.
  2. Do the Base64 encoding on the output of the HMAC signing function to produce the signature string.
Following Java method can be used to generate the signature.
import sun.misc.BASE64Encoder;  
   import javax.crypto.Mac;  
   import javax.crypto.spec.SecretKeySpec;  
   ....  
   private String generateSignature(String signatueBaseStr, String oAuthConsumerSecret, String oAuthTokenSecret) {  
     byte[] byteHMAC = null;  
     try {  
       Mac mac = Mac.getInstance("HmacSHA1");  
       SecretKeySpec spec;  
       if (null == oAuthTokenSecret) {  
         String signingKey = encode(oAuthConsumerSecret) + '&';  
         spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1");  
       } else {  
         String signingKey = encode(oAuthConsumerSecret) + '&' + encode(oAuthTokenSecret);  
         spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1");  
       }  
       mac.init(spec);  
       byteHMAC = mac.doFinal(signatueBaseStr.getBytes());  
     } catch (Exception e) {  
       e.printStackTrace();  
     }  
     return new BASE64Encoder().encode(byteHMAC);  
   }  

That’s all!

Resources
[1] “Creating a signature” [Online]. Available:https://dev.twitter.com/docs/auth/creating-signature. [Accessed: 27-Mar-2014].

2 thoughts on “How to Generate OAuth Signature for twitter in core JAVA

Leave a Comment