4

want to generate signature for oauth login .for this i used HmacSHA1 and base64 algo.please have a look below code stuff.I already visit so many links related this but this gives solution for java plat form [J2EE] not for the Android .same code/ method is working fine and generate signature in the eclipse of java but it throws error in android .

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;


import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;



import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class FitBitActivity extends Activity implements Serializable{
    WebView webView;
    static String authToken;
    Context context = this;
    ProgressDialog progressBar;
    String finalAuthToken = "";
    String finalAuthTokenSecrate = "";
    String finalEncodedUserID = "";
    String authVerifer = "";
    String tempAuthToken = "";
    String fitbitUser = "";
    SharedPreferences sharedPref;
    String userid;
    static String TAG = "FitBitActivity";

    String Authorization = ""; 
    String res= "";
    static String timestamp ;
    String auth_nonce="456236281" ; 
     static String nonce ;
   // String parameters;
    static String consumerKey= "XXXXXX your key XXXXX";
    private ProgressDialog pDialog;

     Random RAND ;
     private static final String HMAC_SHA1 = "HmacSHA1";


    @SuppressLint({ "NewApi", "NewApi", "NewApi" })
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fitbit_activity);

        Long tsLong = System.currentTimeMillis()/1000;
        timestamp = tsLong.toString();

        RAND = new Random();
        nonce = timestamp + RAND.nextInt();


        generateSignature();


    }

    public static  void generateSignature() {
        // TODO Auto-generated method stub
        String base_string =
                "POST&https%3A%2F%2Fapi.fitbit.com%2Foauth%2Frequest_token&oauth_consumer_key%3D"
 +consumerKey+"%26"+"oauth_nonce%3D"+nonce+"%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D"+timestamp+"%26oauth_version%3D1.0";
        String key = "sign";


         try {
                Mac mac = Mac.getInstance("HmacSHA1");
                SecretKeySpec secret = new SecretKeySpec(key.getBytes("UTF-8"), mac.getAlgorithm());
                mac.init(secret);
                byte[] digest = mac.doFinal(base_string.getBytes());

                String enc = new String(digest);

                // Base 64 Encode the results
                String retVal = Base64.encodeBase64String(digest);

              // byte[] retVal = Base64.encode(base_string.getBytes(), Base64.NO_WRAP);

               // byte[] retVal = Base64.encodeBase64(base_string.getBytes()); 

                Log.e(TAG, "String: " + base_string);
                Log.e(TAG, "key: " + key);
                Log.e(TAG, "result: " + retVal.toString());             

            } catch (Exception e) {
                System.out.println(e.getMessage());
            }

    }


}

1 Answer 1

16

The org.apache.commons.codec.binary.Base64 class is not part of the standard Android APIs. To fix the problem, just use the standard Base64 class that comes with Android by replacing these lines:

import org.apache.commons.codec.binary.Base64;
...
String retVal = Base64.encodeBase64String(digest);

by:

import android.util.Base64;
...
String retVal = Base64.encodeToString(digest, Base64.DEFAULT);
Sign up to request clarification or add additional context in comments.

4 Comments

let me correct ,you are telling about base64 from "android.util.Base64" package ?
It's strange, if he didn't add the org.apache.commons.codec.binary.Base64 to his app, it can't pass the compilation, how can that Exception occurs?
@Leog - there could be a variety of reasons for that. Most likely it's a configuration problem in the ant/gradle script but it could also be an issue with the JDK that he's using to compile the app. Either way, since Android already provides classes for Base64 encoding/decoding, including the whole commons-codec package doesn't provide any benefit.
+1 for my side brother .its working fine . I spent 1 day behind this ,so many extra libs for import as per the solution on google but can't getting output.don't know where i am wrong ,I also tried base64 of utils package but same error occur .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.