com.tapcentive.minimalist.JWTHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.tapcentive.minimalist.JWTHelper.java

Source

/*
 * Copyright 2015 Tapcentive, Inc. 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

package com.tapcentive.minimalist;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;

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

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Base64;

/**
 * The Class JWTHelper creates a JSON Web Token in order to securely interact with the Tapcentive 
 * server.
 * Note that this class is provided as an example only. Security best practices would drive this 
 * functionality on to the client Web Server in order to minimize keys being present in the
 * mobile application.
 */
public class JWTHelper {
    private int _keyid;
    private String _key;

    /**
     * Instantiates a new JWT helper.
     *
     * @param keyid the keyid
     * @param key the key
     */
    public JWTHelper(int keyid, String key) {
        this._keyid = keyid;
        this._key = key;
    }

    /***
     * Generates a JSON Web Token. This token uses the supplied application key to sign the token
     * content which should uniquely identify the client's customer (e.g. a loyalty number, email
     * etc.) and contain any Tapcentive audience IDs assigned to this customer. This example does
     * not require that either parameter be present.
     * @param originalBody
     * @param audiences
     * @param customerId
     * @return
     */
    public String createJWT(JSONObject originalBody, List<String> audiences, String customerId) {

        try {
            JSONObject header = new JSONObject();
            JSONObject body = new JSONObject(originalBody.toString());
            header.put("typ", "JWT");
            header.put("alg", "HS256");
            body.put("iss", _keyid);

            if ((audiences != null) && (audiences.size() > 0)) {
                JSONArray attrArray = new JSONArray(audiences);
                body.put("audiences", attrArray);
            }

            if (customerId != null) {
                body.put("customer_xid", customerId);
            }

            String signedContent = Base64.encodeToString(header.toString().getBytes("UTF-8"), Base64.NO_WRAP) + "."
                    + Base64.encodeToString(body.toString().getBytes("UTF-8"), Base64.NO_WRAP);
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(_key.getBytes("UTF-8"), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            String signature = Base64.encodeToString(sha256_HMAC.doFinal(signedContent.getBytes("UTF-8")),
                    Base64.NO_WRAP);
            return signedContent + "." + signature;
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

    /***
     * 
     * Converts a string to a byte array
     */
    static byte[] hex2bytes(String str) {

        byte[] bytes = new byte[str.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(str.substring(2 * i, 2 * i + 2), 16);
        }
        return bytes;
    }
}