title: Creating JSON Web Token in Java
body: <p>I am trying to create a JSON Web Token in order to use it for making refresh token call with Google Analytics API access. I have taken service account approach. </p>
  
  <p>As per this approach I need to :</p>
  
  <ol>
  <li>Create Service Account</li>
  <li>Add the Email Address created for the Analytics app with Google Analytics account.</li>
  <li>Download the priavte key file(.p12)</li>
  <li>Use this priavate key and email address for constructing JWT which will be subsequently used for making HTTP POST call to google auth server in order to get refresh token.</li>
  </ol>
  
  <p>I am not sure whether my approach of creating JWT is correct or not. The sample available as <code>JWT_Handler.java</code> on the Google Code site talks about creating JWT with claim part and request payload only with header and signature part missing. This is confusing with googles guidelines for creating JWT for refresh token  where the JWT involves three parts : </p>
  
  <ol>
  <li>JWT Header</li>
  <li>JWT Claim</li>
  <li>Signature</li>
  </ol>
  
  <p>All the three parts are Base64Url encoded. I tried following code :</p>
  
  <pre><code>import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.nio.charset.Charset;
  import java.security.KeyStore;
  import java.security.PrivateKey;
  import java.security.Signature;
  import java.util.Calendar;
  import java.util.Enumeration;
  
  import com.google.api.client.util.Base64;
  import com.google.gson.JsonObject;
  public class TestJWT {
  
  private final static Charset UTF8_CHARSET = Charset.forName("UTF-8");
  private static KeyStore myStore = null;
  private static FileInputStream in_cert = null;
  public static void main(String[] args) {
      PrivateKey privateKey = null;       
      try {
          in_cert = new FileInputStream(
                  "D://Google Analytics//ClientLogin//Analytics//%$%%$%$%-privatekey.p12");
  
      } catch (FileNotFoundException e) {
          e.printStackTrace();
      }       
      try {
          myStore = KeyStore.getInstance("PKCS12");
          myStore.load(in_cert, "notasecret".toCharArray());
          String alias = "";       
          Enumeration objEnumeration = myStore.aliases();
          while (objEnumeration.hasMoreElements() == true) {
              alias = (String) objEnumeration.nextElement();              
              privateKey = (PrivateKey) myStore.getKey(alias,
                      "notasecret".toCharArray());
          }
      } catch (Exception e1) {
          e1.printStackTrace();
      }
  
      JsonObject header = new JsonObject();
      header.addProperty("alg", "RS256");
      header.addProperty("typ", "JWT");
  
      Calendar cal = Calendar.getInstance();      
      cal.set(1970, 01, 01);      
      String iat = Long.toString((System.currentTimeMillis() - cal.getTimeInMillis())/1000);
      String exp = Long.toString((System.currentTimeMillis() - cal.getTimeInMillis())/1000 + 60000L);
  
      JsonObject claim = new JsonObject();
      claim.addProperty("iss", "$$%$^%&amp;^!%@#$@developer.gserviceaccount.com");
      claim.addProperty("scope", "https://www.googleapis.com/auth/devstorage.readonly");
      claim.addProperty("aud", "https://accounts.google.com/o/oauth2/token");
      claim.addProperty("access_type", "offline");
      claim.addProperty("exp", exp);
      claim.addProperty("iat", iat);
  
  
      System.out.println("Header : " + header);
      String headerStr = header.toString();
      System.out.println("claim : " + claim);
      String claimStr = claim.toString();
  
  
      try {
  
          byte[] headerArr = headerStr.getBytes(UTF8_CHARSET);
          System.out.println(Base64.encodeBase64String(headerArr));
  
          byte[] claimArr = claimStr.getBytes(UTF8_CHARSET);
          System.out.println(Base64.encodeBase64String(claimArr));
  
          String inputStr = Base64.encodeBase64String(headerArr) + "." + Base64.encodeBase64String(claimArr);
  
          System.out.println("Input String : " + inputStr);
          Signature signature = Signature.getInstance("SHA256withRSA");
          signature.initSign(privateKey);
          signature.update(inputStr.getBytes(UTF8_CHARSET));
          System.out.println("Sign : " + signature.sign());
  
          System.out.println("Base64url encoded sign : " + Base64.encodeBase64String(signature.sign()));
  
          System.out.println("Final JWT : " + Base64.encodeBase64String(headerArr) + "." + Base64.encodeBase64String(claimArr) + "." + Base64.encodeBase64String(signature.sign()));
  
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
  
  }
  </code></pre>